如何使用 ZF2 中的数组表单设置使字段验证依赖于另一个字段?
How to make a field validation dependent on another field usind array form setup in ZF2?
在我的表单中,我有一个字段 foo
,它在数据库 table 中应该是唯一的。所以我在它的验证器列表中添加了一个 Zend\Validator\Db\NoRecordExists
:
namespace Bar\Form\Fieldset;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Db\Adapter\AdapterInterface;
class BuzFieldset extends Fieldset implements InputFilterProviderInterface
{
protected $dbAdapter;
public function __construct($name = null, $options = []) {...}
public function setDbAdapter(AdapterInterface $dbAdapter) {...}
public function init()
{
$this->add([
'name' => 'id',
'type' => 'hidden'
]);
$this->add(
[
'name' => 'foo',
'type' => 'text',
'options' => [...],
'attributes' => [
'required' => 'required',
'class' => 'form-control'
]
]);
...
}
public function getInputFilterSpecification()
{
return [
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Regex',
'options' => [
'pattern' => '/.../',
'message' => _(...)
]
],
[
'name' => 'Zend\Validator\Db\NoRecordExists',
'options' => [
'table' => 'buz',
'field' => 'foo',
'adapter' => $this->dbAdapter
]
]
]
],
...
];
}
}
现在我想使用相同的表单来更新条目,当然无法验证表单。因此,我需要根据字段 id
对该字段进行 NoRecordExists
验证。如果设置了 id
(这意味着它正在更新,而不是创建),则应应用所有验证器(例如此处 Regex
),但不应用此验证器。怎么做?
您可以查看 Callback 验证器。此验证器将使您能够访问表单上下文,从而允许您获取其他字段的值。在 Callback
验证器中使用 NoRecordExists
验证器使其依赖。像这样的东西。我没有对此进行测试,但你会明白的。
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Callback',
'options' => [
'callback' => function($value, $context = []) {
if (empty($context['id'])) {
return $this->noRecordExistsValidator->isValid($value);
}
return true;
},
],
]
]
]
您需要将 NoRecordExistsValidator
作为此表单的依赖项注入 class,或者更好的是创建一个单独的 InputFilter
和完全设置 [=14] 的相应工厂=] 并将该实例注入 Fieldset
对象。
在我的表单中,我有一个字段 foo
,它在数据库 table 中应该是唯一的。所以我在它的验证器列表中添加了一个 Zend\Validator\Db\NoRecordExists
:
namespace Bar\Form\Fieldset;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Db\Adapter\AdapterInterface;
class BuzFieldset extends Fieldset implements InputFilterProviderInterface
{
protected $dbAdapter;
public function __construct($name = null, $options = []) {...}
public function setDbAdapter(AdapterInterface $dbAdapter) {...}
public function init()
{
$this->add([
'name' => 'id',
'type' => 'hidden'
]);
$this->add(
[
'name' => 'foo',
'type' => 'text',
'options' => [...],
'attributes' => [
'required' => 'required',
'class' => 'form-control'
]
]);
...
}
public function getInputFilterSpecification()
{
return [
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Regex',
'options' => [
'pattern' => '/.../',
'message' => _(...)
]
],
[
'name' => 'Zend\Validator\Db\NoRecordExists',
'options' => [
'table' => 'buz',
'field' => 'foo',
'adapter' => $this->dbAdapter
]
]
]
],
...
];
}
}
现在我想使用相同的表单来更新条目,当然无法验证表单。因此,我需要根据字段 id
对该字段进行 NoRecordExists
验证。如果设置了 id
(这意味着它正在更新,而不是创建),则应应用所有验证器(例如此处 Regex
),但不应用此验证器。怎么做?
您可以查看 Callback 验证器。此验证器将使您能够访问表单上下文,从而允许您获取其他字段的值。在 Callback
验证器中使用 NoRecordExists
验证器使其依赖。像这样的东西。我没有对此进行测试,但你会明白的。
'foo' => [
'required' => true,
'validators' => [
[
'name' => 'Callback',
'options' => [
'callback' => function($value, $context = []) {
if (empty($context['id'])) {
return $this->noRecordExistsValidator->isValid($value);
}
return true;
},
],
]
]
]
您需要将 NoRecordExistsValidator
作为此表单的依赖项注入 class,或者更好的是创建一个单独的 InputFilter
和完全设置 [=14] 的相应工厂=] 并将该实例注入 Fieldset
对象。