2013-03-25 85 views
2

我将dinamically textfields添加到模型中称为名称的属性,但我喜欢将验证规则设置为视图中数组名称中的每个名称,是否可以在CForm模型中取消验证规则?例如,我想验证点击按钮后需要每个名称。Can Yii框架验证CFormModel类的规则函数中的字段数组

这是观点与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(); ?> 

回答

0

首先,你需要指定model.Like中的关系码:在搜索功能,那么

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

使用这样的关系:

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

并在您的视图中使用该图像:

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

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

我用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); 
    } 
} 

OK,但对于客户端验证?看来这应该是可能的,但我还没有测试过它:

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;   
}