I am using a simple captcha on my pop-up dialog using bPopup plugin.
You can refer the captcha code to this jsfiddle: https://jsfiddle.net/Mazzu/hspxaeqa/
HTML:
<span id="popup-button-email">Click Here!</span>
<div id="popup-second"> <a class="b-close">x<a/>
<simple-captcha valid="captchaValid"></simple-captcha>
</div>
JS:
app.directive('simpleCaptcha', function() {
return {
restrict: 'E',
scope: { valid: '=' },
template: '<input ng-model="a.value" ng-show="a.input" style="width:2em; text-align: center;"><span ng-hide="a.input">{{a.value}}</span> {{operation}} <input ng-model="b.value" ng-show="b.input" style="width:2em; text-align: center;"><span ng-hide="b.input">{{b.value}}</span> = {{result}}',
controller: function($scope) {
var show = Math.random() > 0.5;
var value = function(max){
return Math.floor(max * Math.random());
};
var int = function(str){
return parseInt(str, 10);
};
$scope.a = {
value: show? undefined : 1 + value(4),
input: show
};
$scope.b = {
value: !show? undefined : 1 + value(4),
input: !show
};
$scope.operation = '+';
$scope.result = 5 + value(5);
var a = $scope.a;
var b = $scope.b;
var result = $scope.result;
var checkValidity = function(){
if (a.value && b.value) {
var calc = int(a.value) + int(b.value);
$scope.valid = calc == result;
} else {
$scope.valid = false;
}
$scope.$apply(); // needed to solve 2 cycle delay problem;
};
$scope.$watch('a.value', function(){
checkValidity();
});
$scope.$watch('b.value', function(){
checkValidity();
});
}
};
});
POPUP:
$('#popup-button-email').bind('click', function(e) {
// Prevents the default action to be triggered.
e.preventDefault();
// Triggering bPopup when click event is fired
$('#popup-second').bPopup();
});
All looks fine, except one thing.
After I close the pop-up, and I open another pop-up, it didn't reload the captcha, which is very odd.
Any ideas how to reload the captcha after I close the pop-up?
Thanks
You need to update just one or two things. In checkvalidity function of directive
$scope.$apply()causing $digest cycle to run when it's already in progress, so breaking it, to avoid that you can have checkvalidity function in scope variable of directive's controller & remove this explicit calling of $apply. Also, as$('#popup-second').bPopup()calling does not actually re-render the directive so it always showing first time loaded results of directive. So what you can do is have ng-if on that directive element in your view & toggle it ononClose&onOpenevents of bPopup(). So your template can be:Update checkvalidity function inside directive as:
And in controller of view call bPopup as:
So in this way the directive is re-created every time you trigger it. So it'll give expected results & thanks to isolated scope you can reuse it multiple times on same view or different view of the app.
Working plunker