【问题标题】:Can Yii framework validate array of fields in the rule function of a CFormModel classYii框架可以验证CFormModel类的规则函数中的字段数组吗
【发布时间】:2013-03-15 14:24:47
【问题描述】:

我正在向模型中名为名称的属性添加动态文本字段,但我喜欢为视图中数组名称中的每个名称设置验证规则,这可以在 CForm 模型中取消验证规则吗? ,例如,我想验证单击按钮后是否需要每个名称。

这是带有 CActiveForm 的视图代码

<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'test',
'enableClientValidation'=>true,
'clientOptions'=>array(
    'validateOnSubmit'=>true,
),
)); ?>

<p class="note">Campos <span class="required">*</span> son obligatorios.</p>

<div class="row">
    <?php echo $form->labelEx($model,'Age'); ?>
    <?php echo $form->textField($model,'age'); ?>
    <?php echo $form->error($model,'age'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'Name'); ?>
    <?php echo $form->passwordField($model,'names[0]'); ?>
    <?php echo $form->error($model,'names[0]'); ?>

</div>

<div class="row">
    <?php echo $form->labelEx($model,'Name'); ?>
    <?php echo $form->passwordField($model,'names[1]'); ?>
    <?php echo $form->error($model,'names[1]'); ?>

</div>

<div class="row buttons">
        <?php echo CHtml::submitButton('test'); ?>
    </div>

<?php $this->endWidget(); ?>

【问题讨论】:

    标签: php yii frameworks yii-cform


    【解决方案1】:

    首先你需要在模型中指定关系。比如:

    'user' => array(self::BELONGS_TO, 'User', 'user_id'),
    

    然后在搜索功能中使用这样的关系:

    $criteria->with=array('user');
    

    并在您的视图中使用它,例如:

    array(
    'name'=>'username_search',
    'value'=>'$data->user->username',
    'header'=>'Posted By',
    ),
    

    【讨论】:

      【解决方案2】:

      您需要编写一个自定义验证器,假设要验证的属性是一个数组,并将另一个验证器的结果应用于其每个元素。

      我使用this validator 作为起点;在稍微清理和尽可能简化之后,我得到了这个代码进行服务器端验证:

      protected function validateAttribute($object, $attribute)
      {
          $value = $object->$attribute;
      
          if (!is_array($value) ) {
              $this->addError($object, $attribute, "TODO: error message");
              return;
          }
          else if ($this->isEmpty($value)) {
              if (!$this->allowEmpty) {
                  $this->addError($object, $attribute, "TODO: error message");
              }
      
              return;
          }
      
          // $this->validator and $this->parameters are supposed to be
          // attributes of your custom validator class that you set from
          // inside rules().
          $validator = self::createValidator(
              $this->validator,
              $object,
              array($attribute),
              $this->parameters);
      
          $errors = array();
      
          // Iterate over $value, validating each item in turn.
          // Since $validator may be a filtering validator, we need to make
          // sure that any changes it makes to the validated item stick, so
          // we iterate by reference and do a bit of back and forth shuffling.
          foreach($value as $key => &$item) {
              $object->$attribute = $item; // the only way
              $validator->validateAttribute($object, $attribute);
              $item = $object->$attribute; // make any changes stick
      
              if ($object->hasErrors($attribute)) {
                  $errors[$key] = $object->gerErrors($attribute);
                  $object->clearErrors($attribute);
              }
          }
      
          unset($item); // always a good idea after foreach by reference
          $object->$attribute = $value; // undo the damage
      
          // And now decide what to do with $errors, which is per-item.
          // This should be good:
          foreach ($errors as $key => $error) {
               $object->addError("$attribute[$key]", $error);
          }
      }
      

      好的,但是客户端验证呢?看来这应该是可能的,但我没有测试过:

      public function clientValidateAttribute($object,$attribute)
      {
          // Since this is copy/pasted from above, it's an obvious candidate
          // for refactoring into a private method. I 'm keeping it simple.
          $validator = self::createValidator(
              $this->validator,
              $object,
              array($attribute),
              $this->parameters);
      
          $js = '';
      
          // No need for filtering support here (I think...)
          foreach($value as $key => $item) {
              $object->$attribute = $item;
              $js .= $validator->clientValidateAttribute($object, $attribute);
          }
      
          return $js;        
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-01
        • 1970-01-01
        相关资源
        最近更新 更多