How to get the selected option of a radion button element in Zend Framework 2? - zend-framework2

In a Fieldset I have an Element\Radio foo and Element\Text bar.
public function init()
{
$this->add(
[
'type' => 'radio',
'name' => 'foo',
'options' => [
'label' => _('foo'),
'value_options' => [
[
'value' => 'a',
'label' => 'a',
'selected' => true
],
[
'value' => 'b',
'label' => 'b'
]
]
]
...
]);
$this->add(
[
'name' => 'bar',
'type' => 'text',
'options' => [
'label' => 'bar',
...
],
...
]);
}
The validation of the field bar is depending on the selected foo option. It's easy to implement, if I can get the selected value of foo:
public function getInputFilterSpecification()
{
return [
'bar' => [
'required' => $this->get('foo')->getCheckedValue() === 'a',
...
],
];
}
But there is no method Radio#getCheckedValue(). Well, I can iterate over the $this->get('foo')->getOptions()['value_options'], but is it really the only way?
How to get (in the Fieldset#getInputFilterSpecification()) the selected option of a Zend\Form\Element\Radio?

The selected option gets POSTed to the server along with everything else from the HTML form and is all of this is available in validators through the $context array.
You can create a conditionally required field by using a callback validator and the $context array like this:
public function getInputFilterSpecification() {
return [
'bar' => [
'required' => false,
'allow_empty' => true,
'continue_if_empty' => true,
'required' => true,
'validators' => [
[
'name' => 'Callback',
'options' => [
'callback' => function ($value, $context) {
return $context['foo'] === 'a'
},
'messages' => [
\Zend\Validator\Callback::INVALID_VALUE => 'This value is required when selecting "a".'
]
]
]
]
],
];
}
That would check if 'foo' is equal to 'a', i.e. option 'a' is selected and return true when it is, which marks the input as valid, and false when it's not, marking the input invalid.

Related

Shopware 6 Plugin - text snippet not deleted on uninstall plugin - order custom field label

We created custom fields within our plugin for orders and for products.
Shopware creates text snippets for the custom fields labels.
These should be removed when uninstalling the plugin.
It works for the products custom field.
...
'customFields' => [
[
'name' => 'product_custom_field_name_dummy',
'type' => CustomFieldTypes::BOOL,
'config' => [
'type' => 'checkbox',
'componentName' => 'sw-field',
'customFieldType' => 'checkbox',
'label' => [
self::GER_ISO => 'Label GER',
self::EN_ISO => 'Label EN',
Defaults::LANGUAGE_SYSTEM => 'Label EN',
]
],
]
],
'relations' => [
[
'entityName' => ProductDefinition::ENTITY_NAME,
],
],
...
But not for the orders custom fields.
...
'customFields' => [
[
'name' => 'order_custom_field_name_dummy_one',
'type' => CustomFieldTypes::TEXT,
'config' => [
'customFieldType' => CustomFieldTypes::TEXT,
'label' => [
self::GER_ISO => 'Order Label GER',
self::EN_ISO => 'Order Label EN',
Defaults::LANGUAGE_SYSTEM => 'Order Label EN',
]
],
],
[
'name' => 'order_custom_field_name_dummy_two',
'type' => CustomFieldTypes::SELECT,
'config' => [
'customFieldType' => CustomFieldTypes::SELECT,
'componentName' => 'sw-single-select',
'label' => [
self::GER_ISO => 'Order Label GER 2',
self::EN_ISO => 'Order Label EN 2',
Defaults::LANGUAGE_SYSTEM => 'Order Label EN 2',
],
'options' => [
...
]
]
],
[
'name' => 'order_custom_field_name_dummy_three',
'type' => CustomFieldTypes::DATETIME,
'config' => [
'customFieldType' => CustomFieldTypes::DATETIME,
'label' => [
self::GER_ISO => 'Order Label GER 3',
self::EN_ISO => 'Order Label EN 3',
Defaults::LANGUAGE_SYSTEM => 'Order Label EN 3',
]
],
],
[
'name' => 'order_custom_field_name_dummy_four',
'type' => CustomFieldTypes::SELECT,
'config' => [
'customFieldType' => CustomFieldTypes::SELECT,
'componentName' => 'sw-single-select',
'label' => [
self::GER_ISO => 'Order Label GER 4',
self::EN_ISO => 'Order Label EN 4',
Defaults::LANGUAGE_SYSTEM => 'Order Label EN 4',
],
'options' => [
...
]
],
],
],
'relations' => [
[
'entityName' => OrderDefinition::ENTITY_NAME,
],
],
...
Is this a problem Shopware has with order custom fields or did we possibly make a mistake when creating the order custom fields?
Edit:
The custom fields are created on install method und removed on uninstall method inside the plugin via the CustomFieldSetRepository.
Edit:
This is how we delete the custom fields on uninstall:
public function uninstallCustomFieldSet() {
$customFieldSet = $this->getCustomFieldSet(self::CUSTOM_FIELD_SET_NAME);
if ($customFieldSet instanceof CustomFieldSetEntity) {
$this->customFieldSetRepository->delete([['id' => $customFieldSet->getId()]], $this->context);
}
}
protected function getCustomFieldSet(string $customFieldSetName): ?CustomFieldSetEntity {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('name', $customFieldSetName));
$criteria->addAssociation('customFields');
$criteria->addAssociation('relations');
$customFieldSet = $this->customFieldSetRepository->search($criteria, $this->context)->first();
if ($customFieldSet instanceof CustomFieldSetEntity) {
return $customFieldSet;
} else {
return null;
}
}
The author mentions that Shopware 6 confirms that it's a bug.
I am creating an answer to this question even though it was already answered in the comments so that it can be accepted & this question resolved.

How to set selected option on choiceType sonata admin bundle

setting default/ selected option for choice field in symfony3 sonata admin bundle?
For example :
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
/**
* #inheritdoc
*/
public function configureFormFields(FormMapper $formMapper) {
parent::configureFormFields($formMapper);
$formMapper->add('type', ChoiceType::class, [
'label' => 'config.label_type',
'choices' => [
'config.label_permanent' => 'permanent',
'config.label_automatic' => 'automatic',
'config.label_temporary' => 'temporary'
],
'required' => false
]);
}
How to make the _permanent_ as selected value ?
This post doesn't help me out
setting default value in symfony2 sonata admin bundle
You can try with something like this:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
/**
* #inheritdoc
*/
public function configureFormFields(FormMapper $formMapper) {
parent::configureFormFields($formMapper);
$subject = $this->getSubject();
if (null === $subject->getId()) {
$subject->setType('permanent');
}
$formMapper->add('type', ChoiceType::class, [
'label' => 'config.label_type',
'choices' => [
'config.label_permanent' => 'permanent',
'config.label_automatic' => 'automatic',
'config.label_temporary' => 'temporary'
],
'required' => false
]);
}

How to enable displaying the global label unsing FormMultiCheckbox in ZF2?

I'm using Zend\Form\Element\MultiCheckbox with Zend\Form\View\Helper\FormMultiCheckbox:
MyFieldset.php
// namespace ...;
// use ....;
class MyFieldset extends Fieldset
{
// ...
public function init()
{
parent::init();
$this->add(
[
'type' => 'multi_checkbox',
'name' => 'mymulticheckbox',
'options' => [
'label' => _('global label'),
'label_attributes' => [
'class' => 'col-md-3',
],
'value_options' => [
[
'value' => 'foo',
'label' => 'FOO',
],
[
'value' => 'bar',
'label' => 'BAR',
],
[
'value' => 'buz',
'label' => 'BUZ',
],
]
],
]
);
}
// ...
}
myform.phml
use Zend\Form\View\Helper\FormMultiCheckbox;
echo $this->formMultiCheckbox($myFieldset->get('mymulticheckbox'), FormMultiCheckbox::LABEL_PREPEND);
It works, but the "global label" is not displayed. It gets displayed, when I'm using Zend\Form\View\Helper\FormElement, but the FormMultiCheckbox seems to ignore the "global label".
How to make FormMultiCheckbox display the label of the checkbox list?
Have you tried with formRow(). For me it works. This does not appear to be managed in formMultiCheckbox(). See lines 182-193, file zend-form/src/View/Helper/FormRow.php.
// Multicheckbox elements have to be handled differently as the HTML standard does not allow nested
// labels. The semantic way is to group them inside a fieldset
if ($type === 'multi_checkbox'
|| $type === 'radio'
|| $element instanceof MonthSelect
|| $element instanceof Captcha
) {
$markup = sprintf(
'<fieldset><legend>%s</legend>%s</fieldset>',
$label,
$elementString
);

How to validate empty input in Zend Framework 2

I'm doing a registration form in ZF2, but I don't get how to validate. Validation seems not working.
I'm adding the validators array, but it doesn't work anyways. I don't know how can I fix that.
This is my code of controller:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Form\Formularios;
use Zend\Db\Adapter\Adapter;
use Application\Modelo\Entity\Usuarios;
class FormularioController extends AbstractActionController
{
public $dbAdapter;
public function indexAction()
{
return new ViewModel();
}
public function registroAction()
{
if($this->getRequest()->isPost())
{
$this->dbAdapter=$this->getServiceLocator()->get('Zend\Db\Adapter');
$u=new Usuarios($this->dbAdapter);
//echo "se recibiĆ³ el post";exit;
$data = $this->request->getPost();
$u->addUsuario($data);
return $this->redirect()->toUrl($this->getRequest()->getBaseUrl().'/application/formulario/registro/1');
}else
{
//zona del formulario
$form=new Formularios("form");
$id = (int) $this->params()->fromRoute('id', 0);
$valores=array
(
"titulo"=>"Registro de Usuario",
"form"=>$form,
'url'=>$this->getRequest()->getBaseUrl(),
'id'=>$id
);
return new ViewModel($valores);
}
}
}
this is my form code with validator
class Formularios extends Form
{
public function __construct($name = null)
{
parent::__construct($name);
$this->add(array(
'name' => 'name',
'required' => true,
'allow_empty' => false,
'options' => array(
'label' => 'Nombre Completo',
),
'attributes' => array(
'type' => 'text',
'class' => 'input'
),
'filters' => [ ['name' => 'StringTrim'], ],
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Ingrese Nombres.',
))))
));
$this->add(array(
'name' => 'lastname',
'required' => true,
'options' => array(
'label' => 'Apellido',
),
'attributes' => array(
'type' => 'text',
'class' => 'input'
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'Ingrese Apellidos.',
))))
));
Thanks in advance
First problem.
$data = $this->request->getPost(); should be $data = $this->getRequest()->getPost();
Second problem is that you call your validators direclty when you build your form in the view, which is wrong. The right way to do is via an inputFilter. Now, there are many ways to to this, for example: with or without a factory called from your model or via the for class with a form element manager
I will show you the model way with a factory since it's easier for new comers.
namespace MyModule\Model;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class MyModel implements InputFilterAwareInterface
{
/**
* #var null $_inputFilter inputFilter
*/
private $_inputFilter = null;
// some more code like exhnageArray get/set method
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add(
$factory->createInput([
'name' => 'id',
'required' => false,
'filters' => [
['name' => 'Int'],
],
])
);
$inputFilter->add(
$factory->createInput([
"name"=>"title",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
'max' => 200,
],
],
],
])
);
$inputFilter->add(
$factory->createInput([
"name"=>"text",
"required" => true,
'filters' => [
['name' => 'StripTags'],
['name' => 'StringTrim'],
],
'validators' => [
['name' => 'NotEmpty'],
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],
])
);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
Third proble. DO NOT EVER use serviceManager in controller. It's a really really really bad practice. Instead use a factory.

\Zend\Form\Element\Collection validation as a whole

I have form with collection. And i attach validation to whole collecion - i just want to check the existence of certain relations between elements of the collection.
And it works great. in the case of wrong data - form does not pass the "isValid()" test.
But there is one problem. formElementErrors / getMessages didnt return anything.
What i do wrong?
My form:
class Form implements InputFilterProviderInterface {
/**
* #return array
*/
public function getInputFilterSpecification()
{
return [
[
'name' => 'legend',
'required' => true,
'allowEmpty' => false,
'validators' => [
['name' => 'Callback', 'options' => [
'messages' => [
\Zend\Validator\Callback::INVALID_VALUE => 'Wrong',
],
'callback' => function ($values, $context=[]) {
return false;
},
]],
]
],
];
}
public function init()
{
$this->add(
[
'name' => 'legend',
'type' => 'Zend\Form\Element\Collection',
'options' => [
'label' => 'Legenda',
'count' => 2,
'should_create_template' => true,
'allow_add' => true,
'template_placeholder' => '__placeholder__',
'target_element' => [
'type' => 'Narzedzie\Form\Legenda\LegendyOpcjeFieldset',
],
],
]
);
}
}
And view:
$element = $NarzedzieForm->get('legend');
var_dump($element->getMessages()); // in case of error - empty array!
echo $this->formElementErrors($element); // in case of error - empty string
echo $this->formColleciton($element);
Maybe you need to add both messages?
'messages' => [
\Zend\Validator\Callback::INVALID_VALUE => 'Wrong VALUE',
\Zend\Validator\Callback::INVALID_CALLBACK => 'Wrong CALLBACK',
],
as perhaps the invalid callback message is being suppressed as you are only supplying one? I would hope it would fall back to the default. But then all this validator message stuff seems a bit stupid to me the way it is done.
Looks like you have an error in your callback, which might be throwing an exception and is being caught in the validator in the try catch statement maybe?
should be?
function ($values, $context=[]) {
foreach ($values as $value) {
if ($value['el'] == '1') return false;
}
return true;
},
as in $values not $value for the array in the foreach? Probably want to check that key is set too, with an isset($value['el'])?

Resources