我正在将dinamically textfields添加到名为names的模型中的属性中,但我喜欢将验证规则设置为视图中数组名称中的每个名称,这是否可以在CForm模型中执行未验证的验证规则?例如,我想验证单击Button后是否需要每个名称。
这是带有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 :(得分: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);
}
}
好的,但客户端验证怎么样?看来这应该是可能的,但我还没有测试过它:
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;
}
答案 1 :(得分:0)
首先,你需要在模型中指定关系。喜欢:
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
然后在搜索功能中使用该关系,如:
$criteria->with=array('user');
在您的视图中使用它,如:
array(
'name'=>'username_search',
'value'=>'$data->user->username',
'header'=>'Posted By',
),