Zend Framework 2/3 Multicheckbox禁用ISEMPTY错误



默认情况下,当没有选择这些选项时,多切克框元素会触发错误消息:

 array (size=1)
  'checkbox' => 
    array (size=1)
      'isEmpty' => string 'Value is required and can't be empty' (length=36)

我发现可以使用函数getInputFilterSpecification禁用该消息:

class MyForm extends Form  implements InputFilterProviderInterface{
  private $inputFilter;
  public function __construct($name = null){
    parent::__construct($name);

    $this->add([
                'name' => 'checkbox',
                'type' => 'checkbox',
                'attributes' => [],
                'options' => [
                             'value_options' =>[
                                                [
                                                'value' => '0',
                                                //'selected' => true,
                                                'label' => 'One',
                                                'label_attributes'=>[],
                                                'attributes' => [],
                                                ],
                                                [
                                                'value' => '1',
                                                'label' => 'Two',
                                                'label_attributes'=>[],
                                                'attributes' => [],
                                                ],
                                                [
                                                'value' => '2',
                                                'label' => 'Three',
                                                'label_attributes'=>[],
                                                'attributes' => [],
                                                ],
                             ],
                ],
    ]);

  }//construct
   public function getInputFilterSpecification() {
        return array(
         'checkbox'=>['required'=>false,],
        );  
    }

}//class

这种方法的唯一"问题"是您必须为多挑选元素的所有实例指定名称和相对选项;拥有10个不同的多封面框,输入换算器的规格将是:

public function getInputFilterSpecification() {
   return array(
     'checkbox1'=>['required'=>false,],
     'checkbox2'=>['required'=>false,],
     'checkbox3'=>['required'=>false,],
     ...   
   );  
}

...好吧,这还不错,但是由于元素(和/或所有值选项(接受属性required,但实际上被视为需要,并且

该消息来自哪里?看来是一个预先签名的无验证器,但我在Zend的Mulicheckbox类或父级Checkbox类中都没有找到任何跟踪。

真的没有更好的方法吗?

我自己找到了答案。

Zend的Multicheckbox元素扩展了实现InputProviderInterface的复选框元素。

和复选框(第165行(有:

public function getInputSpecification()
{
    $spec = [
        'name' => $this->getName(),
        'required' => true,
    ];
    if ($validator = $this->getValidator()) {
        $spec['validators'] = [
            $validator,
        ];
    }
    return $spec;
}

ZendInputFilterInput类中检索所需参数,如果true(始终为true(,则添加了无empterty验证器。

ergo:没有办法通过元素的选项来改变这种行为(再次:愚蠢(。


无论如何,可以通过使用扩展Multicheckbox的自定义元素来完成某些操作(这实际上是我已经在做的,出于其他原因(:

namespace FormFormElement;
use ZendInputFilterInputProviderInterface;
use ZendModuleManagerFeatureViewHelperProviderInterface;
use ZendFormElementMultiCheckbox;
class BootstrapMultiCheckbox extends MultiCheckbox implements  ViewHelperProviderInterface, InputProviderInterface{
  protected $attributes = [
                          'type' => 'bootstrapMultiCheckbox',
                          ];
  public function getViewHelperConfig(){return array('FormFormViewHelperBootstrapMultiCheckboxHelper', null);}
  public function getInputSpecification(){
    $spec = [
            'name' => $this->getName(),
            'required' => false,
            ];
    if ($validator = $this->getValidator()) {
      $spec['validators'] = [$validator,];
    }
    return $spec;
  }
}

我刚刚从原始的复选框元素复制了getInputSpecification函数,并将其设置为false。这样,不再需要将所需参数指定到表单的getInputFilterSpecification函数中。

显然,如果您已经使用了Multicheckbox的自定义版本,则此解决方案是有道理的,否则...进行自己的考虑。


更新:处理元素所需的属性,实际使用

基本上,您将以这种方式处理所需的属性(在此处使用自定义无线电元素(:

//Form __construct:
$this->add([
                'name' => 'radio',
                'type' => BootstrapRadio::class,
                'attributes' => ['required' => true,],
                'options' => [
                             'value_options' =>[...],
                ],
    ]);

然后:

//BootstrapRadio Element:
public function getInputSpecification(){
    //If required==true, then the notEmpty validator will be added (see above)
    $required=$this->getAttribute('required');
    $spec = [
            'name' => $this->getName(),
            'required' => $required,
            ];
    if ($validator = $this->getValidator()) {
      $spec['validators'] = [$validator,];
    }
    return $spec;
  }

另外您可能需要将所需属性分配给仅几个选项(无线电元素无意义(:

//Form __construct:
$this->add([
                'name' => 'checkbox',
                'type' => BootstrapMultiCheckbox::class,
                'options' => [
                             'value_options' =>[
                                                [
                                                'value' => '0',
                                                'label' => 'One',
                                                ],
                                                [
                                                'value' => '1',
                                                'label' => 'Two',
                                                'attributes' => ['required' => true,],
                                                ],
                                                [
                                                'value' => '2',
                                                'label' => 'Three',
                                                'attributes' => ['required' => true,],
                                                ],
                             ],
                ],
    ]);

然后:

//Custom element:
namespace FormFormElement;
use ZendInputFilterInputProviderInterface;
use ZendModuleManagerFeatureViewHelperProviderInterface;
use ZendFormElementMultiCheckbox;
use ZendValidatorNotEmpty;
use FormFormValidatorBootstrapMulticheckboxValidator;
class BootstrapMultiCheckbox extends MultiCheckbox implements  ViewHelperProviderInterface, InputProviderInterface{
  protected $attributes = [
                          'type' => 'bootstrapMultiCheckbox',
                          ];
  protected $requiredValues=false;
  public function getViewHelperConfig(){return array('FormFormViewHelperBootstrapMultiCheckboxHelper', null);}
  public function getInputSpecification(){

    $required=$this->setIsRequired();
    $spec = [
            'name' => $this->getName(),
            'required' => $required,
            ];
    if ($validator = $this->getValidator()) {
      $spec['validators'] = $this->requiredValues ? [$validator, new BootstrapMulticheckboxValidator($this->requiredValues)] : [$validator];
    }
    return $spec;
  }
  public function setIsRequired(){
    $value=$this->getValue();
    if(!$value && $this->getAttribute('required')){return true;}
    foreach ($this->getValueOptions() as $key => $option){
      if(isset($option['attributes']['required'])){$this->requiredValues[$key]=$option['value'];}
    }
    if(!$value && $this->requiredValues){return true;}
    return false;
  }
} 

最后:

//custom validator
namespace FormFormValidator;
use Traversable;
use ZendStdlibArrayUtils;
use ZendValidatorAbstractValidator;
use ZendValidatorNotEmpty;
class BootstrapMulticheckboxValidator extends AbstractValidator
{
    const IS_EMPTY = 'isEmpty';
    protected $requiredValues;
    protected $messageTemplates = [
        self::IS_EMPTY => 'Value is required and can't be empty',
    ];
    public function __construct($requiredValues)
    {
      $this->requiredValues=$requiredValues;
      parent::__construct(null);
    }
    public function isValid($values)
    {
       foreach($this->requiredValues as $required){
         if(!in_array($required, $values)){
           $this->error(self::IS_EMPTY);
           return false;
         }
       }
       return true;
    }
} 

注意:取决于您如何通过将Novalidate属性添加到您的表单中的自定义元素,以禁用浏览器的验证:

class BootstrapForm extends Form  implements InputFilterProviderInterface{
  private $inputFilter;
  public function __construct($name = null){
    parent::__construct($name);
    $this->setAttribute('novalidate',true);
    $this->add([
                'name' => 'checkbox',
    [...]

最新更新