why recaptcha doesn't work with polymer - google-api

this is my element
<dom-module id="user-verify">
<style>
paper-dialog {
--paper-dialog-background-color: white;
width: 348px;
height: 205.594px;
}
</style>
<template>
<paper-dialog id="id_verify" modal>
<h2><content></content></h2>
<div id="maincontainer">
<div class="g-recaptcha"
data-sitekey="6Lc0pAkTAAAAAGcsiru1MX6kjI6HGV8mbImc0cwk"
data-callback="recaptchaCallback"></div>
</div>
<div class="buttons">
<paper-button dialog-confirm id="varify_button" disabled>Ok</paper-button>
</div>
</paper-dialog>
</template>
<script>
Polymer({
is: "user-verify",
attached: function(){
this.$.id_verify.open();
},
recaptchaCallback: function(){
this.$.varify_button.disabled = false;
}
});
</script>
<script src='https://www.google.com/recaptcha/api.js'></script>
However, it doesn't work when i put the javascript of recaptcha in side the head of the html, so i can only put it inside the element. But now ,the data-callback function doesn't work. How to solve this? Or my code have some bugs?

Your callback recaptchaCallback is a method of the polymer object and not public function available for the recaptcha API. The way you register the function (via String) the API assumes your callback is global.
I would simply switch to attaching all the recaptcha-logic programmatically:
...
attached: function() {
grecaptcha.render(this.$.maincontainer.querySelector('.g-recaptcha'), {
'sitekey' : 'your_site_key',
'callback' : this.recaptchaCallback,
});
this.$.id_verify.open();
}
...

Related

Unable to Programmatically invoke the invisible recaptcha challenge by ID

We have a set up with multiple forms on a single page. We are rendering each recaptcha successfully, however I'm struggling to invoke the recaptcha challenge programatically targeted to an ID.
Looking at the docs (https://developers.google.com/recaptcha/docs/invisible#programmatic_execute) my understanding is that I can pass an ID with the execute command so the response is filled into g-response within the correct form, otherwise the response defaults to the first g-response it finds on the page (which is no good for anything other than the first form on the page).
I've tried it with a slightly modified version of Googles own example, however we get the error message 'Invalid site key or not loaded in api.js: recaptcha123' even though the key is correct.
Does anyone have any idea how we might get this working?
<html>
<head>
<script>
function onSubmit(token) {
alert('thanks ' + document.getElementById('field').value);
}
function validate(event) {
event.preventDefault();
if (!document.getElementById('field').value) {
alert("You must add text to the required field");
} else {
grecaptcha.execute('recaptcha123');
}
}
function onload() {
var element = document.getElementById('submit');
element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form>
Name: (required) <input id="field" name="field">
<div id="recaptcha123" class="g-recaptcha"
data-sitekey="XXXXXXXXXXXXXXXX"
data-callback="onSubmit"
data-size="invisible"></div>
<button id="submit">submit</button>
</form>
<script>onload();</script>
</body>
</html>
The following code works:
<html>
<head>
<title>reCAPTCHA demo: Explicit render after an onload callback</title>
<script>
var onSubmit = function(token) {
console.log('success!');
};
var onloadCallback = function() {
widgetId1 = grecaptcha.render('recaptcha', {
'sitekey' : 'XXXXXXXXXXXXXXXXXX',
'callback' : onSubmit
});
};
</script>
</head>
<body>
<script src="/wp-content/themes/kc_water_care_services/js/pristine.min.js"></script>
<form action="?" method="POST" id="contactForm">
<div class="form-group">
<label for="name">Name (required)</label>
<input type="text" required data-pristine-required-message="Please enter your name"
id="name" name="name" />
</div><!--/.form-group-->
<div id="recaptcha" data-size="invisible"></div>
<input id="submit" type="submit" value="Submit">
</form>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer>
</script>
</body>
</html>
<script>
var form = document.getElementById("contactForm");
// create the pristine instance
var pristine = new Pristine(form);
form.addEventListener('submit', function (event) {
event.preventDefault();
// check if the form is valid
var valid = pristine.validate(); // returns true or false
if(valid == true){
grecaptcha.execute(widgetId1);
}
});
</script>
Turns out the id doesn't refer to the css ID, it refers to an ID created when you use the render function.

Load data when change neon-page

I'm new in Polymer and I trying to do mobile app use Polymer and Cordova.
I use neon-animated-pages for pretty animation, and now I have some issue with iron-ajax. When I open project in browser on localhost:8080 all my pages already loaded and if I change page I want to make iron-ajax request. How can i do this?
example index.html
<dom-module id="my-app">
<template>
<style>
// some style
</style>
<app-header-layout fullbleed>
<app-header>
<app-toolbar>
<div main-title>Title</div>
<paper-input label="page" value="{{page::change}}"></paper-input>
<paper-icon-button icon="menu"></paper-icon-button>
</app-header>
<div class="content">
<neon-animated-pages id="page"
selected="{{page}}"
attrForSelected="index"
entry-animation="slide-from-right-animation"
exit-animation="slide-left-animation">
<neon-animatable index="0"><login-app name="login"></login-app></neon-animatable>
<neon-animatable index="1"><profile-page name="profile"></profile-page></neon-animatable>
<neon-animatable index="2"><secondary-page name="secondary"></secondary-page></neon-animatable>
</neon-animated-pages>
</div>
<footer>
© Polymer project
</footer>
</app-header-layout>
</template>
<script>
Polymer({
is: 'my-app',
behaviors: [GlobalsBehaviour],
properties: {
page: {
type: Number,
reflectToAttribute: true,
value: 0
}
}
});
</script>
And example some page with iron-ajax:
<dom-module id="secondary-page">
<template>
<style>
:host {
display: block;
}
</style>
<div>secondary PAGE</div>
<div>Var value - {{my}}</div>
<iron-ajax
id="login"
url="https://www.some.url/"
method="get"></iron-ajax>
</template>
<script>
Polymer({
is: 'secondary-page',
properties: {
my: {
type: String,
value: 'my'
}
}
});
</script>

Polymer Iron-Ajax Does not Display Data

I'm facing a problem, when i using Polymer's iron-ajax element.
I have a custom element like that:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<dom-module id="first-element">
<template>
<!-- Stylesheet-->
<style>
::host{
display:block;
}
</style>
<!-- Element content -->
<h1>
{{yolo}}
</h1>
<iron-ajax
auto
url="http://s3.amazonaws.com/codecademy-content/courses/ltp4/forecast-api/forecast.json"
handle-as="json"
on-response="handleResponse"
last-response="ajaxResponse"></iron-ajax>
<span>{{ajaxResponse.city_name}}</span>
</template>
<script>
Polymer({
is: "first-element",
properties: {
yolo: {
type: String,
value: 'YOLOOO'
}
},
handleResponse: function(){
console.log('Jobs Done')
}
});
</script>
</dom-module>
The handleResponse function, also display's browsers developer console, so that request is working correctly. Databinding also working correctly, i can also see my "yolo" properties value.
But, it doesn't display data, i also use brackets e.g [[ajaxResponse.city_name]]
How can I solve that? Thanks for help!
You are not binding iron-ajax last-response attribute to any of your polymer element properties, it's supposed to be : last-response = "{{ajaxResponse}}".
In addition the amazon request need to be loaded over https.
Here is Plunkr to see it in action.
You can check this PolyCast on iron-ajax if you want to learn more.
<dom-module id="first-element">
<template>
<!-- Stylesheet-->
<style>
::host {
display: block;
}
.icon{
width:35px;
height:auto;
float:right;
position:relative;
top:-20px;
}
</style>
<!-- Element content -->
<h1>
{{yolo}}
</h1>
<iron-ajax auto url="https://s3.amazonaws.com/codecademy-content/courses/ltp4/forecast-api/forecast.json" handle-as="json" on-response="handleResponse" last-response="{{ajaxResponse}}"></iron-ajax>
<h1>{{ajaxResponse.city_name}}</h1>
<template is="dom-repeat" items="{{ajaxResponse.days}}" index-as="day_no">
<div>
<hr>
<span>Day : {{day_no}}</span>
<br>
<img src="{{item.icon}}" alt="" class="icon">
<span> High: {{item.high}} C</span>
<br>
<span> Low: {{item.low}} C</span>
</div>
</template>
</template>
<script>
Polymer({
is: "first-element",
properties: {
yolo: {
type: String,
value: 'YOLOOO'
},
ajaxResponse: {
type: Array
}
},
handleResponse: function(e) {
console.log(e.detail.xhr.response);
}
});
</script>
</dom-module>

Ember not updating the view on model change

This fiddle has the starter kit recreated, with and extra button that alters the model.
http://jsfiddle.net/UjacC/1/
However, when clicking change, the array changes, but the view is not being updated. Why?
<title>Ember Starter Kit</title>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
<button id="btnChange">change model</button>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item}}</li>
{{/each}}
</ul>
</script>
<script>
$(document).ready(function(){
console.log(stuff);
$("#btnChange").click(function(){
stuff.push("d");
console.log("change",stuff);
});
});
</script>
</body>
App = Ember.Application.create();
var stuff = ["a","7","b","c"];
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return stuff;
}
});
Instead of stuff.push you need to use Embers pushObject which will notify listeners of an object that there was a change to it.
EDIT:
Here's the updated jsfiddle: http://jsfiddle.net/UjacC/2/

Create function to slide div down and up all the time

I'm trying to build a function that will slide down and up the specific div I'll mention later in the script, here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
div { background:yellow; border:1px solid #AAA; width:80px; height:80px; margin:0 5px; float:left; }
div.colored { background:green; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<button id="run">Run</button>
<div></div>
<div id="mover"></div>
<div></div>
<script>
$("button#run").click(function(){
$("div:animated").toggleClass("colored");
});
function animateIt() {
return $(this).slideToggle(5000, animateIt);
}
$("div#mover").animateIt();
</script>
</body>
</html>
But it gives me this error "Uncaught TypeError: Object [object Object] has no method 'animateIt'"
Here's a fiddle
Thanks in advance. Shia...
animateIt is not a jQuery method. Call it as a regular function, and pass in the element:
function animateIt ( $element ) {
$element.slideToggle(5000, function (){
animateIt($element);
});
}
animateIt( $("div#mover") );​
Here's your fiddle, updated: http://jsfiddle.net/ZcQM7/2/
If you want it to be a jQuery method, you'll have to turn it into a plugin:
$.fn.animateIt = function () {
var $this = this;
this.slideToggle(5000, function () {
$this.animateIt();
});
};
$("div#mover").animateIt();​
Here's your fiddle again, with another update: http://jsfiddle.net/ZcQM7/1/
animateIt() is a function that you declared in your code and does not belong to jQuery.
You should call it directly:
function animateIt() {
return $("#mover").slideToggle(5000, animateIt);
}
animateIt();

Resources