2010-08-31 1 views
4

Я пытаюсь создать форму, которая изменяет проверку поля на основе опции выбора из поля формы html.Возможна ли динамическая проверка Symonfy 1.4?

Ex: если пользователь выбирает вариант 1 из раскрывающегося списка «параметры», я хочу, чтобы поле «метрика» проверялось как sfValidatorInteger. Если пользователь выбирает вариант 2 из поля «параметры», я хочу, чтобы поле «метрика» проверялось как sfValidatorEmail и т. Д.

Итак, внутри публичной функции configure() {У меня есть оператор switch, чтобы фиксировать значение «options» »и создать валидатор на основе этого значения, возвращенного из« параметров ».

1.) Как я могу определить значение «параметров»? Я пробовал:

$this->getObject()->options 
$this->getTaintedValues() 

Единственное, что в настоящее время работает для меня, но это не совсем MVC:

$params = sfcontext::getInstance()->getRequest()->getParameter('options'); 

2.) После того, как я захватил эту информацию, как можно назначить значение «метрики» в другое поле? («метрика» не является реальным столбцом в db). Поэтому мне нужно назначить значение «метрики» для разных полей, таких как «электронная почта», «возраст» ... В настоящее время я обрабатываю это на post validator, как это, просто интересно, могу ли я назначить значение в configure ():

$this->validatorSchema->setPostValidator(new sfValidatorCallback(array('callback' => array($this, 'checkMetric')))); 

public function checkMetric($validator, $values) { 

} 

Спасибо!

ответ

6

Вы хотите использовать валидатор сообщений. Попробуйте сделать что-то подобное в вашей форме:

public function configure() 
{ 
    $choices = array('email', 'integer'); 
    $this->setWidget('option', new sfWidgetFormChoice(array('choices' => $choices))); //option determines how field "dynamic_validation" is validated 
    $this->setValidator('option', new sfValidatorChoice(array('choices' => array_keys($choices))); 
    $this->setValidator('dynamic_validation', new sfValidatorPass()); //we're doing validation in the post validator 
    $this->mergePostValidator(new sfValidatorCallback(array(
    'callback' => array($this, 'postValidatorCallback') 
))); 
} 

public function postValidatorCallback($validator, $values, $arguments) 
{ 
    if ($values['option'] == 'email') 
    { 
    $validator = new sfValidatorEmail(); 
    } 
    else //we know it's one of email or integer at this point because it was already validated 
    { 
    $validator = new sfValidatorInteger(); 
    } 
    $values['dynamic_validation'] = $validator->clean($values['dynamic_validation']); //clean will throw exception if not valid 
    return $values; 
} 
+0

Благодарим за помощь! Я заработал так. Я не знал о mergePostValidator и $ validator-> clean(). Знаете ли вы способ привязать имя поля к сообщению об ошибке, которое вызывается $ validator-> clean()?. В этом случае это будет поле «option». –

0

1) В валидаторе сообщений доступны значения using the $values parameter. Просто используйте $ values ​​['options'], и это должно быть хорошо ... или вы хотите получить доступ к этим значениям из другой части вашего кода? $ this-> getObject() -> widgetSchema ['options'] тоже должен работать, как только ваша форма привязана к объекту.

2) Метод configure() вызывается в конце конструктора формы, поэтому значения не привязаны и не доступны пока, если вы не инициализируете свою форму объектом из db (который не требует какой-либо проверки) , Но если вы хотите инициализировать свою форму из $ _POST, почтовый валидатор определенно подходит для ИМХО.

+0

Благодарим вас за ответ. Это очень полезно, и я решил перенести свой код на валидатор сообщений и захватить значения $, как вы предложили. Благодарю. –

0

я получил ошибку проверки появляться рядом с полем, бросая sfValidatorErrorSchema вместо sfValidatorError.

$values['dynamic_validation'] = $validator->clean($values['dynamic_validation']); 

... становится ...

try 
{ 
    $values['dynamic_validation'] = $validator->clean($values['dynamic_validation']); 
} 
catch(sfValidatorError $e) 
{ 
    $this->getErrorSchema()->addError($e, 'dynamic_validation'); 
    throw $this->getErrorSchema(); 
} 

Не уверен, что это лучший способ, чтобы получить этот результат, но это, кажется, работает для меня на данный момент.