我有一个相当复杂的表格,它以选项卡格式呈现。表单中的任何一个字段集都需要完成,所以我正在考虑使用 OptionalInputFilter。我遇到问题的字段集是一个集合。我已将输入过滤器配置为可以与集合一起使用,但可选方面似乎无法解决问题。需要明确的是,所需的效果是用户可以添加一组项目,其中每个元素都经过过滤/验证,或者用户将其留空,并且它通过验证。
有问题的字段集:
class EventFieldset extends Fieldset
{
public function __construct($name = null, $options = [])
{
parent::__construct('Events', $options);
}
public function init()
{
$this->add([
'name' => 'date',
'type' => Date::class,
'options' => [
'label' => 'Date',
'label_attributes' => [
'class' => 'col-form-label'
],
],
'attributes' => [
'class' => 'form-control ',
'required' => true,
],
]);
$this->add([
'name' => 'description',
'type' => Textarea::class,
'options' => [
'label' => 'Description',
'label_attributes' => [
'column' => 'md-2',
'class' => 'col-form-label'
],
],
'attributes' => [
'class' => 'form-control',
'minlength' => '10',
'required' => true,
],
]);
$this->add([
'name' => 'hours',
'type' => Text::class,
'options' => [
'label' => 'Hours',
'label_attributes' => [
'column' => 'md-2',
'class' => 'col-form-label'
],
'column' => 'md-10'
],
'attributes' => [
'class' => 'has-event-duration duration-only form-control'
],
]);
}
}
上述字段集的输入过滤器:
class EventInputFilter extends OptionalInputFilter
{
public function init()
{
parent::init();
$this->add([
'name' => 'date',
'validators' => [
[
'name' => Date::class,
'options' => [
'format' => 'Y-m-d',
'strict' => true,
]
],
],
'filters' => [
['name' => StripTags::class],
[
'name' => DateTimeFormatter::class,
'options' => [
'format' => 'Y-m-d'
]
]
]
]);
$this->add([
'name' => 'description',
'required' => true,
'validators' => [
[
'name' => StringLength::class,
'options' => [
'min' => 5,
'max' => 25600
]
]
],
'filters' => [
['name' => StripTags::class],
['name' => StringTrim::class]
]
]);
$this->add([
'name' => 'hours',
'required' => true,
'validators' => [
['name' => AlnumValidator::class],
],
'filters' => [
['name' => StripTags::class],
['name' => Alnum::class]
]
]);
}
}
注意它是如何扩展 OptionalInputFilter 的。
表格:
class MyForm extends Form
{
public function init()
{
parent::init();
//other elements / fieldsets removed for brevity
$this->add([
'name' => 'manualRecords',
'type' => ManuallyEnteredRecordsFieldset::class,
]);
$this->add([
'type' => Csrf::class,
'name' => 'csrf',
'options' => [
'csrf_options' => [
'timeout' => 600,
],
],
]);
$this->add([
'name' => 'Submit',
'type' => Submit::class,
'options' => [
'label' => 'Submit',
'variant' => 'outline-primary'
],
'attributes' => [
'class' => 'btn btn-primary',
'value' => 'Submit'
]
]);
}
}
class ManuallyEnteredRecordFieldset extends Fieldset
{
public function init()
{
//other elements here - removed for brevity
$this->add([
'name' => 'Events',
'type' => Collection::class,
'options' => [
'count' => 1,
'allow_add' => true,
'should_create_template' => true,
'target_element' => [
'type' => EventFieldset::class
],
]
]);
最后,在表单工厂中添加输入过滤器:
class MyFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$form = new MyForm();
$form->setInputFilter($this->getInputFilter($container->get('InputFilterManager')));
return $form;
}
protected function getInputFilter(InputFilterPluginManager $inputFilterPluginManager) : InputFilter
{
//other input filters applied - removed for brevity
$eventInputFilter = $inputFilterPluginManager->get(EventInputFilter::class);
$baseInputFilter = new InputFilter();
$collectionInputFilter = new CollectionInputFilter();
$collectionInputFilter->setInputFilter($eventInputFilter);
$manualRecordInputFilter = new OptionalInputFilter(); //note - also an OptionalInputFilter
$manualRecordInputFilter->add($collectionInputFilter, 'Events');
$baseInputFilter->add($manualRecordInputFilter, 'manualRecords');
return $baseInputFilter;
}
}
当我提交带有数据的表单时,即使添加了 1->N 行的集合,也可以很好地验证它。如果没有输入任何数据(由于它是从可选的 Inputfilter 构建的,我希望它仍然会通过),我会收到以下 inputfilter 错误消息:
["manualRecords"] => array(2) {
["Events"] => array(1) {
[0] => array(3) {
["date"] => array(2) {
["isEmpty"] => string(36) "Value is required and can't be empty"
}
["description"] => array(1) {
["isEmpty"] => string(36) "Value is required and can't be empty"
}
["hours"] => array(1) {
["isEmpty"] => string(36) "Value is required and can't be empty"
}
}
}
这不是行为应该遵循的方式: https ://docs.laminas.dev/laminas-inputfilter/optional-input-filters/