Zend validate interprets "disabled" input fields as empty - zend-framework2

I again ran into a problem I just can´t seem to comprehend.
I have a form element like so:
$this->add(array(
'type' => 'datetime',
'name' => 'modifiedTime',
'options' => array(
'label' => 'Modified Time',
),
'attributes' => array(
'disabled' => 'disable',
),
));
This one does get filled correctly trough my entity(I am using doctrine) like so:
/**
* #ORM\Column(type="datetime", nullable=true, name="modified_time")
*
* #Form\Exclude()
*/
protected $modifiedTime;
public function getModifiedTime(){
return $this->modifiedTime;
}
public function populate($data)
{
$this->modifiedTime = date_create($data['modifiedTime']);
}
This works completly fine as long as the "disabled" attribute is not set. But as soon as it is I get a validation error claiming "Value is required and can't be empty" eventhou the value is set in the input.
any Ideas?

The disabled attribute does exactly what it states. It disables the html-form-element. This means, that when you sent the form back to your service/controller, that form field will not be posted.
Now my assumption is that you don't want users to edit some data that's displayed in an EditForm? In this case, don't use disabled, better choose readonly for displaying purpose.
On Server-Side, simply ignore what the user is posting. As when it's readonly, the data will still be sent and can be modified by the user using browser-dev-tools ;)

Related

ZF2 input validator for required not empty only when not null

I'm building a form with input filters and all in Zend Framework 2. I'm using arrays to configure my inputs and filters and validators. So, say I have some input:
array(
'name' => 'foo',
'required' => true,
)
On the page, there's some jQuery code that might optionally hide this input. If it does, it hides and disables the input. On submit, var_dump on the form data gives foo => null (probably because it didn't actually submit in the post data and so the form input is never given a value). If the input is not hidden and not filled out then on submit it has foo => string '' (length=0).
I want to require the input to have a value if the input is used. So, are there some settings I can add to my config array that will allow null to pass validation, but reject the empty string value? Or do I need to write a custom validator?
Yes, you ought to use NotEmpty validator.
$inputFilter = new \Zend\InputFilter\InputFilter ();
$inputFilter->add ([
'name' => 'foo',
'validators' => [
[
'name' => 'not_empty',
'options' => [
'type' => 'string'
]
]
]
]);
$form->setInputFilter ($inputFilter);

How to get an array of values for the router "segment"?

I use a form with a multiupload. My addAction save information regarding the downloaded files in the database, and obtains an array lastInsrtId() values. If the upload was successful, I need to be redirected to editAction, where a user can see a list of downloaded files and user can edit file attributes such as title, description and alt attribute for images for each downloaded file using this files list. How do I pass an array of values ​​in the route? Here is my code addAction:
// upload success
$fileIds = $this->getContentService()->makeFiles($parent, $data);
return $this->redirect()->toRoute('sc-admin/file/edit', array('ids' => $fileIds));
Here is the definition for a route that should display a list of files for editing:
'edit' => array(
'type' => 'segment',
'options' => array(
'route' => '/edit[/:ids]',
'defaults' => array(
'controller' => 'sc-file',
'action' => 'edit',
),
),
),
But it generates an error for editAction
rawurlencode() expects parameter 1 to be string, array given
I do not want to use the session whenever the parameters necessary to pass an array of values, because it is a matter solely routing.
Ever seen this url?
http://foo.bar/baz?array(1=>2,3=>4)
Probably not. You got an error message so do as the error message says. This has nothing to do with Zend Framework, this is basic PHP (too many people often forget what's the core...).
array('ids' => serialize($data))
See php:serialize() and php:unserialize()

Adding a strategy to a Zend\Form\Element\Collection

Is there a way to add a Hydration strategy to a Zend\Form\Element\Collection element? I tried it the normal way:
$hydrator = new ClassMethods();
$hydrator->addStrategy('language', new LanguageStrategy($em));
$hydrator->addStrategy('items', new UnitItemsStrategy($em));
$this->setHydrator($hydrator);
With the element:
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'items',
'options' => array(
'label' => 'Items',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'target_element' => array(
'type' => 'Application\Form\UnitItemFieldset',
),
),
));
But the hydrator strategy just never gets called. When I just remap it to another element like text it gets called. So it seems to have to do with the element being a Zend\Form\Element\Collection.
Actually, they can be just added to collections as to any other element. In my case there have been several mistakes in using collections correctly:
did not call $form->prepare() in the view script
did not use ClassMethods hydrator for a while (due to debugging), but I do not know why this should be a problem (yet it was, but probably I am missing something else)
Another possible problem I just found out:
your method used by ClassMethods (e.g. setItems in my case) is not callable, then ZF will not call the hydrator strategy either

How to call function in model from form in zf 2?

Im using zend framework 2. I want to call a function in model from zend form.
The situation is Im having a combo box & I need to bind data from database to fill its options and value.
This is my select tag in zend form
$this->add(array(
'name' => 'ddlcountry',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Country',
'value_options' => (here I've to call function),
),
));
For this value option I want to call a function which is in model below is my function in model:
public function fetchcountry()
{
$this->adapter = $this->getServiceLocator()->get('db');
$dbAdapterConfig = $this->adapter;
$dbAdapter = $dbAdapterConfig;
$driver = $dbAdapter->getDriver();
$connection = $driver->getConnection();
$result = $connection->execute("CALL sp_showcountry()");
$statement = $result->getResource();
$resultdata = $statement->fetchAll(\PDO::FETCH_OBJ);
return $resultdata;
}
before you write such a Question, please check at least the first 10 Questions on this Page, as your Question has been asked SEVERAL Times lately ;)
Please refer to my answer provided here:
How to get data from different model for select?
Or refer to my Blogpost, which covers your problem in detail
Zend\Form\Element\Select and Database-Values

How to apply classes to labels using Zend\Form and add line endings within the rendered form?

I've followed the tutorial for Zend Framework 2 and I see on the rendered form that the convention for binding the label is to wrap the input element in the label tags as opposed to using the 'for' attribute. While the tutorial didn't cover it, I deduced (correctly) that the attributes array allows for setting a class on the input element itself but what I really want to do is apply a class onto the label defined under options.
Here's an example used in the tutorial (from AlbumForm.php):
$this->add(array(
'name' => 'title',
'attributes' => array(
'class' => 'required', // <- I added this
'type' => 'text',
),
'options' => array(
'label' => 'Title',
),
));
That will render as this:
<label><span>Title</span><input name="title" class="required" type="text" value=""></label>
Optionally, I could live with having the class applied to the span tag but I'd prefer to use the class on the label and then use css child selectors for the span and input elements
I've re-read the tutorial plus the comments on the appropriate section and even dug into the Zend\Form API documentation itself and I don't see how I could apply a class attribute to the label in declaring a form element in this manner.
Another minor nitpick with form rendering is that it appears to be rendered inline with no line breaks between form elements. I've gotten around this by adding a line break in the view scripts (add.phtml and edit.phtml) like so:
echo $this->formRow($form->get('title')) . "\n";
However, this seems like a pain to have to do with every echoed form statement within the view and using the formCollection() also renders the entire form output inline. For legibility purposes I'd like to at least have line breaks where appropriate when viewing the source (I'd wish for proper indentation, too, but that seems like a tall order since even IDE's get it wrong much of the time)
So, is there a built-in option for either of these concerns that I'm missing or, alternatively, a way to define a factory or helper? If I'd need to write a helper, I'd want it to apply to all modules.
To add a class to the label use the 'label_attributes' key in your configuration:
$this->add(array(
'name' => 'title',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Title',
'label_attributes' => array(
'class' => 'required',
),
),
));
To add new lines, you can either write your own FormRow view helper or render the label and element separately within your view script like this:
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form) . "\n";
echo $this->formLabel($form->get('title')) . "\n";
echo $this->formInput($form->get('title')) . "\n";
echo $this->formElementErrors($form->get('title'));
// other elements
echo $this->form()->closeTag($form) . "\n";

Resources