Yii: Не работает CAPTCHA при включении ajax-валидации. Помогите себе с нами.

Yii: Не работает CAPTCHA при включении ajax-валидации. Помогите себе с нами. При включённой ajax валидации ('enableAjaxValidation'=>true) капча выдает ошибку и не проходит проверку. Как настроить Captcha и ajax-валидацию формы. Captcha, Ajax validation и сценарии.

Это важно научиться понимать. Ajax Validation или Ajax проверка полей на лету - хорошее дело. Yii обладает такой возможностью. И этим надо пользоваться.

Когда мы только-только добавили возможность комментирования на Loco.ru, естественно мы добавили к форме комментирования проверку с помощью капчи. Мы тогда рассчитывали что всё заработает, но Ajax валидацию пришлось отключить, чтобы Captcha оставалась работоспособна (включали 'enableAjaxValidation'=>true, капча начинала писать ошибку, что код не прошёл проверку). Вобщем "забили" тогда на ajax-помпезность*.

Итак, пришло знание и свет пролился на эту проблему. Если захотите написать комментарий или написать через форму обратной связи, вы увидите как поля проверяются на лету и вам выдаётся ошибка, если что-то неверно. Разбираемся как это сделать. Прежде всего нам помогла тема с форума.

1. В форме views/comment/_form.php включаем ajax валидацию:

'enableAjaxValidation'=>true,

2. В правила модели добавляем сценарий для проверки капчи. Это делается свойством - 'on'. Когда его нет, то считается, что правило используется для всех сценариев. Если оно есть, то сожержит список сценариев, к которым применяется валидатор.

public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			...
			// verifyCode needs to be entered correctly
			array('verifyCode', 'captcha', 'allowEmpty'=>!Yii::app()->user->isGuest || !extension_loaded('gd'), 'on'=>'insert'),
		);
	}

3. Теперь в контроллере дополняем:

protected function newComment($material)
	{
		...
		$comment=new Comment('insert'); //создаём модель Comment и задаём её сценарий как 'insert' 
		if(isset($_POST['ajax']) && $_POST['ajax']==='comment-form') //тут ajax-валидация
		{
			$comment->setScenario('ajax'); //метод, устанавливающий сценарий 'ajax' для модели $comment, созданной выше
			echo CActiveForm::validate($comment);
			Yii::app()->end();
		}
		if(isset($_POST['Comment']))
		{
			$comment->attributes=$_POST['Comment'];		
			//if($comment->validate($comment->attributes)){
				if($material->addComment($comment))
				{
					if($comment->status==Comment::STATUS_PENDING)
						Yii::app()->user->setFlash('commentSubmitted','Благодарим Вас за комментарий. После модерации он будет опубликован.');
					$this->refresh();
				}
			//}
		}
		return $comment;
	}

$comment=new Comment('insert'); эквивалентно:

$comment=new Comment; //создаём модель
$comment->scenario='insert'; // задаём ей сценарий

Таким образом, используя сценарий, мы ввели исключение. Какое и зачем?

Всё просто: 

  • когда работает ajax-валидация, то учитываются все правила из rules, за исключением Captcha (потому что она срабатывает только на сценарий insert);
  • когда жмём кнопку (отправляем форму с данными), всё валидируется и сохраняется (send() сам по умолчанию ещё выполняет validation() перед сохранением).

Теперь ajax проверка не срабатывает на Captcha, а значит та не будет обновляться по асинхронному запросу (невидимо для нас, отсюда ошибки, когда мы видя старую капчу вводим символы с неё, а сравниваются они уже с обновлённой капчей, Qiang Xue в комментариях говорил использовать testLimit и ставить его в "0", "-1", и т.д. ). Но мы ставим капчу в конец, перед кнопкой отправить. А нажатие кнопки и так вызовет проверку, но уже правильную, без исключения.

Вот как будет это выглядеть:

Yii не работает Ajax валидация и Captcha

*Помпезность — подчёркнутая пышная торжественность, тяжеловесность и монументальность, великолепие.

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (3)     Подпишитесь на RSS комментариев к этой статье.

3 комментариев

#627
Temirbek говорит:
September 5, 2012 at 01:53 pm
а что если был введен неправильный код? как вернуться обратно на это страницу и чтобы текст комментариев не терялся?
#633
almix говорит:
September 10, 2012 at 12:51 pm
При вводе неверной капчи, она проверяется при нажатии на кнопку отправить. Она не проверяется по ajax, но как обычно проверяется. И та же страница остаётся с сообщением об ошибке, и заполненные поля никуда не деваются.
#1025
Степан говорит:
November 8, 2013 at 07:05 pm
В yii меня очень раздражает фронтовая валидация, то есть когда нажимаешь на обязательное поле ничего не вводишь, потом нажимаешь на второе и в первом возникает ошибка. Откуда это можно поменять?