简体   繁体   中英

Yii2 Captcha refresh or reload image

I'm using the default Captcha implementation of advanced application template shipped with . I tried many time to find any api property that allows me to add Refresh image link that allows user to generate new Captcha image but I could not figure out how to do that. I tried the following solution depending on Jquery:

<!-- This code is placed just before the closing </body> tag at the end of
"frontend/views/layouts/main.php" -->
<script>
  $("#fox").click(function(event){
    event.preventDefault();
    $("img[id$='-verifycode-image']").click();
  })
</script>

While in the contact.php the view of contactAction I added a link with an id fox to the widget of captcha as the following:

<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
    'template' => '<div class="row"><div class="col-lg-3">{image}<a href="#" id="fox">Refresh</a></div><div class="col-lg-6">{input}</div></div>',
]) ?>

The described solution above, works fine, but It make a must to add unusable code for all application's views except contactAction view or any other view that uses Captcha! because I could not insert the code before including Jquery library. ie in the view, so I inserted it at the end of the layout.

The question here: Is there any solution directly from the yii2 api? or there is any better suggestion to make this jquery code works in the view? ie turning it into pure JavaScript.

The below code worked for me -

form code on view file to generate captcha image -

<?= $form->field($model, 'captcha')->widget(\yii\captcha\Captcha::classname(), [
    'template' => '<div class="col-lg-3">{image} <a href="javascript:;" id="fox">Refresh</a></div><div class="col-lg-3">{input}</div>',
])?> 

model code to validate captcha code -

public function rules()
{
    return [
        [['name', 'city', 'description','email'], 'required'],
        [['captcha'], 'captcha']
    ];
}

and js code to refresh captcha image in layouts/main.php file -

<script>
  $("#fox").on('click',function(e){
    //#testimonials-captcha-image is my captcha image id
    $("img[id$='-captcha-image']").trigger('click');
    e.preventDefault();
  })
</script>

This will solve the issue, we can create a central view as template for captcha and call it everywhere.

<?php
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model \frontend\models\ContactForm */

?>
<div class="row">
    <div class="col-lg-3">{image} <br /><a id="refresh_captcha" href="javascript:;">Refresh Captcha</a></div>
    <div class="col-lg-6">{input}</div>
</div>
<?php
$this->registerJs('
    $(document).ready(function () {
        $("#refresh_captcha").click(function (event) {
            event.preventDefault();
            $(this).parent().children(\'img\').click();
        })
    });
    ');
?>

For Calling, you can use:

<?= $form->field($model, 'verificationCode')->widget(yii\captcha\Captcha::className(),[
                'template' => $this->render("/_partials/captcha_template"),
            ]); ?>

this will allow you run it on all views, as names and ids can be different for each view.

$(this).parent().children(\'img\').click();

Move that to an external file and you should be fine.
Other solution would be to create a widget with the captcha, create a file with the code and when calling the widget register the javascript file.
Or just create a file with the javascript and remember to register it every time you show the captcha.

Go for the first solution, easier, you do not have to build anything, etc. On websites that do not have thousands of concurrent users it will work just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM