Wednesday, April 18, 2012

Make ajax validation true in your captcha in yiiframework

Maybe you want to use your captcha in your yiiframwork to use in ajaxvalidation to be true. By default the setting may use you as ajaxvalidation false. But when you want to make it available to be in ajax validation true a little bit tricky you have to look.
Let's take alook the solution I get when digging the yii forum..

Thanks to the members there.


In the default form page in your yiiframework you should look like this :


<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
 'id'=>'user-form',
 'enableAjaxValidation'=>false,
        'htmlOptions'=>array('enctype'=>'multipart/form-data'),
)); ?>
 
Change into this :
<div class="form">
 <?php
 // Snippet that reloads the captcha image after validation
 $updateCaptcha=<<<EOD
function(form,attribute,data,hasError) {
    var i=form.find('.captcha img').first(),
                h=/^.*\/v\//.exec(i.attr('src'));  // will cut off the number part at the end of image src URL (".../v/123456")
    i.attr('src',h+Math.floor(100000*Math.random()));  // creates a new random number to prevent image caching
    return true;
}
EOD;

 $form=$this->beginWidget('CActiveForm',array(
   'id'=>'user-form',
   'enableAjaxValidation'=>true,
   'focus'=>'login',
   'clientOptions'=>array(
     'validateOnSubmit'=>true,
     'afterValidateAttribute'=>'js:'.$updateCaptcha,
     'afterValidate'=>'js:'.$updateCaptcha,
   ),
   'htmlOptions'=>array('enctype'=>'multipart/form-data'),
 ));
 ?>
Don't forget to add your CCaptcha widget in your form view yiiframework.

<?php if(extension_loaded('gd')): ?>
 <div class="row">
  <?php echo $form->labelEx($model,'verifyCode'); ?>
  <div>
   <?php $this->widget('CCaptcha'); ?>
   <?php echo $form->error($model,'verifyCode'); ?>
   <?php echo $form->textField($model,'verifyCode'); ?>
  </div>

 </div>
 <?php endif?> 
Add the rules in the model
array('captcha','required','on'=>'register'),
    array('captcha',  // Must be _after_ required rule
      'captcha',
      'on'=>'register',
      'captchaAction'=>'komentarUser/captcha',
      'skipOnError'=>true,    // Important: Only validate captcha if 'required' had no error (a.k.a. "if not empty")
    ),
And finally add your actions of captcha in your controller
public function actions(){
  return array(
    // captcha action renders the CAPTCHA image displayed on the contact page
    'captcha'=>array(
      'class'=>'CCaptchaAction',
      'backColor'=>0xFFFFFF,
      'testLimit'=>0,
      
    ),
    'page'=>array(
      'class'=>'CViewAction',
    ),
  );
 }

That's simple to make the ajax validation to be true when using your captcha in yiiframework
NOTE:
But you have to take an attention when you use your form in partial render. you have to set your default action to the controller that you implement the captcha.
<?php if(extension_loaded('gd')): ?>
 <div class="row">
  <?php echo $form->labelEx($model,'verifyCode'); ?>
  <div>
   <?php $this->widget('CCaptcha',array('captchaAction'=>'komentarUser/captcha')); ?>
   <?php echo $form->error($model,'verifyCode'); ?>
   <?php echo $form->textField($model,'verifyCode'); ?>
  </div>

 </div>

1 comment:

  1. This actually worked! Thanks a million, now i can load my captcha via partial form view.

    ReplyDelete