Javascript: Trouble taking user input and running it in another function - javascript

New to the JS world and I have a few questions. I'm trying to take the user's input and run it through another function but seem to be getting stuck. When I accept the user input using window prompt, the code works correctly.
function lookup(address, callback) {
var electionId;
var address = prompt("Enter your address: ");
var req = gapi.client.request({
'path': '/civicinfo/v2/voterinfo',
'params': {
'electionId': electionId,
'address': address
}
});
req.execute(callback);
}
<h1>Places To Vote</h1>
<p>Find a polling location near you.</p>
<div id="results"></div>
However, I'd like to have the user place their information in an input form and click a submit button. I can't seem to get the user input to go through my other functions once an input form is in place. Help? Please excuse my Frankenstein code.
var userSubmitJS = document.querySelector('userSubmit');
var userInputJS = document.querySelector('userInput');
var address;
userSubmitJS.addEventListener('click', function()) {
address = userInputJS.value;
alert(address);
}
function lookup(address, callback) {
var electionId;
var req = gapi.client.request({
'path': '/civicinfo/v2/voterinfo',
'params': {
'electionId': electionId,
'address': address
}
});
req.execute(callback);
}
<h1>Places To Vote</h1>
<p>Find a polling location near you.</p>
<form>
<input id="userInput" type="text" placeholder="Enter your address">
<button type="submit" id="userSubmit">Submit</button>
</form>
<div id="results"></div>

There were two errors in your code:
if you want to get an element by ID, you need to pass # to querySelector (e.g. #userSubmit and #userInput)
an "Uncaught SyntaxError" in your addEventListener (the position of the closing ) was wrong)
To pass address to the lookup function, you can just call
lookup(address, my_callback)
where my_callback is the name of the callback function.
var userSubmitJS = document.querySelector('#userSubmit');
var userInputJS = document.querySelector('#userInput');
var address;
userSubmitJS.addEventListener('click', function(event) {
event.preventDefault();
address = userInputJS.value;
alert(address);
lookup(address, my_callback);
});
function lookup(address, callback) {
console.log('lookup');
// ...
callback();
}
function my_callback() {
console.log('my_callback');
}
<h1>Places To Vote</h1>
<p>Find a polling location near you.</p>
<form>
<input id="userInput" type="text" placeholder="Enter your address">
<button type="submit" id="userSubmit">Submit</button>
</form>
<div id="results"></div>

Related

google invisible recaptcha keeps running without execute

I'm trying to use google invisible recaptcha on my web form (php and codeigniter 3). but somehow whenever I click on the Submit button, the google recaptcha keeps generating questions as if ignoring all the other codes before the execute command. so none of the console.log and alert ever appear. what is wrong with my code?
my code looks like this:
HTML
<form id="form_signup" method="post" action="/signup">
<input type="text" name="username"/>
<div class="g-recaptcha"
id="form_signup-recaptcha"
data-size="invisible"
data-sitekey="<?php echo $mysitekey; ?>"
data-callback="onSubmitFormSignupUser">
</div>
<button type="button" id="formSignup-btnSubmit">
Submit
</button>
</form>
JS
var widgetId = '';
var onLoadRecaptcha = function() {
widgetId = grecaptcha.render('formSignup-btnSubmit', {
'sitekey' : $('#form_signup-recaptcha').attr('data-sitekey'),
'callback' : $('#form_signup-recaptcha').attr('data-callback'),
});
};
var onSubmitFormSignupUser = function(response) {
console.log('response', response);
if ($('[name="username"]').val()) {
alert('yes');
grecaptcha.execute(widgetId);
doSubmitFormToServer('#form_signup');
}
else {
alert('no');
grecaptcha.reset(widgetId);
}
}
var doSubmitFormToServer = function(selector) {
var myData = $(selector).serializeArray();
console.log('send form data', myData);
}
Well, you had a typo in the id, at least, here id="form_signup-recaptcha" and here: 'sitekey' : $('#formSignup-recaptcha').attr('data-sitekey'),, other than that, it is not clear, was it invoked at all, or not, as you've not provided the part of including the script, which should contain ?onload=onLoadRecaptcha parameter.
The code is below, but it won't work here, because of null origin. Check Codepen instead: https://codepen.io/extempl/pen/abOvBZv
sitekey used is one is for testing purposes only, as described here: https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha-v2-what-should-i-do
var widgetId = "";
var onLoadRecaptcha = function() {
widgetId = grecaptcha.render("formSignup-btnSubmit", {
sitekey: $("#form_signup-recaptcha").attr("data-sitekey"),
callback: $("#form_signup-recaptcha").attr("data-callback")
});
};
var onSubmitFormSignupUser = function(response) {
console.log("response", response);
if ($('[name="username"]').val()) {
grecaptcha.execute(widgetId);
doSubmitFormToServer("#form_signup");
} else {
$(".status").text("failed");
grecaptcha.reset(widgetId);
}
};
var doSubmitFormToServer = function(selector) {
var myData = $(selector).serializeArray();
$(".status").text("submitted");
console.log("send form data", myData);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onLoadRecaptcha"></script>
<body>
<form id="form_signup" method="post" action="/signup">
<input type="text" name="username" />
<div
class="g-recaptcha"
id="form_signup-recaptcha"
data-size="invisible"
data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
data-callback="onSubmitFormSignupUser">
</div>
<button type="button" id="formSignup-btnSubmit">
Submit
</button>
<span class="status"></span>
</form>
</body>
it turns out that the solution is so simple.
this code
var onLoadRecaptcha = function() {
widgetId = grecaptcha.render("formSignup-btnSubmit", { // wrong element ID
sitekey: $("#form_signup-recaptcha").attr("data-sitekey"),
callback: $("#form_signup-recaptcha").attr("data-callback")
});
};
should be like this
var onLoadRecaptcha = function() {
widgetId = grecaptcha.render("form_signup-recaptcha", { // corrent element ID
sitekey: $("#form_signup-recaptcha").attr("data-sitekey"),
callback: $("#form_signup-recaptcha").attr("data-callback")
});
};
because the recaptcha element is like this
<div
class="g-recaptcha"
id="form_signup-recaptcha"
data-size="invisible"
data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
data-callback="onSubmitFormSignupUser">
</div>
so basically the parameters for grecaptcha.render should follow the properties in the element that has g-recaptcha class. my mistake was that I used the button id, even though the element with g-recaptcha class was the div.
I don't remember reading about this particular thing in the documentation. I guess I'm too stupid to realize that before this.. I hope this makes things clear for others with the same problem.

how to fix the java script function that it get a json parameters and send it to the url

I have a java program for coupon system and one of the methods is to update company details the code in java:
public Company updateCompanyDetailes(Company companyToUpDate) throws CustomException {
Company companyFromDb = companyRpository.findById(companyToUpDate.getId()).get();
companyFromDb.setPassword(companyToUpDate.getPassword());
companyFromDb.setEmail(companyToUpDate.getEmail());
companyToUpDate = companyRpository.save(companyFromDb);
return companyToUpDate;
}
It works great but when i want to call this method from my HTML page the javascript is crashing all the time and not transfer the company details as an object,
$scope.companyToUpDate = function() {
$scope.hideAll();
$scope.UpdateComp = true;
$scope.executeForCompany = function() {
if ($scope.id == '') {
window.alert("You must enter ID")
}else {
alert("do you want update company?");
var id = $scope.id;
var password = $scope.password;
var email = $scope.email;
var company = {
companyId: id,
email: email,
password: password
};
$http.put('http://localhost:8999/rest/api/admin/updateCompany', company)
.then(function (response){
window.alert('updated');
// $scope.id = '';
//$scope.password = '';
// $scope.email= '';
$scope.hideAll();
$scope.WelcomePage =true;
}, function(error) {
alert('operation failed' + error.data);
});
}
}
}
As I try is rest when I send aJASON with the parameters id, password, and this is the HTML code:
<div class="col-md-9" ng-show="UpdateComp">
<h2>choose company id to update:</h2>
<input type="number" ng-model="id" min="1">ID</input>
<h4>fill the fields (Password is mandatory):</h4>
* Password<input type="text" ng-model="password">
</input>
Email<input
type="text" ng-model="email"></input>
<button type="button" class="btn btn-primary"
ng-click="executeForCompany()">UPD</button>
<div ng-show="UpdateComp" ng-model="company">
</div>
</div>
i am getting the companyId from the user, all the Javascript are working beside this one
i get this error:
java.lang.IllegalArgumentException: The given id must not be null
When you pass data in json from javascript and are catching that json in a Object(Company) then you need to be careful that the keys are the same as defined in class level.
There is an error for id, check that are you getting you data here
var id = $scope.id;
var password = $scope.password;
var email = $scope.email;
by printing or any means you use.
Also in $http.put('http://localhost:8999/rest/api/admin/updateCompany', company) you passing object named company but receiving it as companyToUpDate make them same.

Display output to multiple classes via JavaScript

I am writing a "Gamebook Engine" which offers the possibility of setting a user name. The Name is taken from an input with the id="setUserNameInput" and saved by the function setUserName(). It is displayed / loaded into an element containing the class="displayUserName" and loaded by the function displayUserName(). It works fine with only one class one the page, but as soon as I add more I have to define which one to target as it won't target them all automatically. I have tried to use document.getElementById, document.getElementsByName as well as document.querySelectorAll and document.querySelector, none of which work. (I use Bulma as my CSS Framework, by the way)
Here is the code I have so far (though it will show an error as it cannot access the localStorage inside the snippet):
This page http://scampsblog.com/docs/example-de.html contains an (working, haha) example. Since it is a documentation (page lies on my testing sever, thus the domain) you might want to take a look at http://scampsblog.com/docs/character-enginedotjs-de.html which explains / shows the individual elements (the documentation is in German but I can provide a translation if you need one).
The part of the JS I am struggling with is right in the first line but if you suggest some overall improvements, I will be happy to take them.
var userNameOutput = document.getElementsByClassName('displayUserName')[0];
function setUserName() {
var usernameinput = document.getElementById('setUserNameInput').value;
localStorage.setItem('userName', usernameinput);
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
function displayUserName() {
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
window.onload = function displayUserName() {
if (!localStorage.getItem('userName')) {
setUserName();
} else {
var storedUserName = localStorage.getItem('userName');
userNameOutput.innerHTML = storedUserName;
}
}
<input type="text" class="input" placeholder="Your name goes here" id="setUserNameInput">
<input type="button" class="button" value="Set your username" onclick="setUserName()" />
<input type="button" class="button" value="Display on click" onclick="displayUserName()" />
<br> So you shall be called <span class="displayUserName"></span>! But dont worry, <span class="displayUserName"></span>, it will be all fine.
Instead of getting the first item in the collection (using [0]) you could iterate through it (using for...of) and set the innerHTML of each element having the class displayUserName.
e.g.
var userNameOutputs = document.querySelectorAll('.displayUserName');
for (let ele of userNameOutputs) {
ele.innerHTML = userName;
}
Full code, with some optimizations to structure:
function setUserName() {
var usernameinput = document.getElementById('setUserNameInput').value;
localStorage.setItem('userName', usernameinput);
displayUserName(true); // pass true to avoid recursion
}
function displayUserName(skipSet) {
var userName = localStorage.getItem('userName');
if (!userName && !skipSet) {
setUserName();
} else {
var userNameOutputs = document.querySelectorAll('.displayUserName');
for (let ele of userNameOutputs) {
ele.innerHTML = userName;
}
}
}
window.onload = displayUserName;
<input type="text" class="input" placeholder="Your name goes here" id="setUserNameInput">
<input type="button" class="button" value="Set your username" onclick="setUserName()" />
<input type="button" class="button" value="Display on click" onclick="displayUserName()" />
<br> So you shall be called <span class="displayUserName"></span>! But dont worry, <span class="displayUserName"></span>, it will be all fine.
Working fiddle: https://jsfiddle.net/hosney/3pxfybrc/1/
var userNameOutput = document.getElementsByClassName('displayUserName')[0];
the [0] selects the first element of the array of elements of the class name.

Fill textbox from url query and call function

<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
So basically, I have a page that can track packages for my customers. I want to be able to send them a link in their email that will automatically track their package from the link. ( they don't have to type in their tracking id and click track when they go to my tracking page )
example.com/track?tnum=3298439857
This is what i'm using to track packages.
https://www.17track.net/en/externalcall/single
The basic idea is as follows:
Wait for page to load
Parse the URL and extract needed query parameter
Set the value of the form element
Call the doTrack() function
// Handy function to parse the URL and get a map of the query parameters
function parseQueryParameters(url) {
var qp = {};
if (!url) {
return qp;
}
var queryString = url.split('?')[1];
if (!queryString) {
return qp;
}
return queryString.split('&')
.reduce(function(m, d) {
var splits = d.split('=');
var key = splits[0];
var value = splits[1];
if (key && value) {
m[key] = value;
}
return m;
}, qp);
}
//Wait for page to load
window.onload = function() {
//Extract tnum query parameter
var qp = parseQueryParameters(window.location.href);
//If no parameter is provided, do nothing
if (!qp.tnum) return;
//Set the value of the form element
document.getElementById("tnum").value = qp.tnum;
// Call doTrack
doTrack();
}
//Temporary doTrack function - remove when integrating ;)
function doTrack() {
console.log(document.getElementById("tnum").value)
}
<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
<html>
<head>
<script>
function setURL(){
var dt_value = document.getElementById("tnum").value;
//just test here ..what is coming..
alert(dt_value );
var sjdurl = "example.com/track?tnum="+dt_value;
popup = window.open(sjdurl,"popup"," menubar =0,toolbar =0,location=0, height=900, width=1000");
popup.window.moveTo(950,150);
}
</script>
</head>
<body>
<input type="Text" id="tnum" maxlength="25" size="25"/>
<input type='button' onclick='setURL()' value='SUBMIT'>
</body>
</html>
function doTrack(tnum) {
var trackNumber = tnum;
window.open("example.com/track?tnum="+trackNumber);
}
$(".btn").on('click',function(e) {
e.preventDefault();
var tnum = $('#tnum').val();
if (tnum!="") {
doTrack(tnum);
} else {
return false;
}
});

updating SQL database using ajax and grails

I am working with grails, in springsource tool suite, and I am facing a problem updating the SQL databse. In the page, the user is asked to enter details of his property, say address, city etc., and once clicking on button 'save' the details need to be saved in the database. Now what I need to do is, dynamically add the input fields (of address, city, etc) to the page, everytime the user clicks on button 'add'. So because of this, i need to use AJAX to post the data to the server. However, I am having trouble updating it. Here is the code of the view(.gsp file)-
<head>
<script type="text/javascript">
var rad1, rad2, button1, button2;
function add() {
var newP = document.createElement("p");
var input1, input2,
area = document.getElementsByTagName("form")[0];
input1 = document.createElement("input");
input1.type = "text";
input1.placeholder = "street";
input1.id = "address";
newP.appendChild(input1);
input2 = document.createElement("input");
input2.type = "text";
input2.placeholder = "city";
input2.id = "city"
newP.appendChild(input2);
area.appendChild(newP);
}
</script>
</head>
<body>
<form name='prop' method="post" action="save">
<g:hiddenField name="owners.id" value="${session.user.id }" />
<input type="button" value="+Add" onclick= "add();" ><br>
<input type="button" name="create" id="save_button" class="save" value="save" />
</form>
<script type="text/javascript" src="ajax.js"></script>
</body>
Here is what my Ajax code looks like in a separate ajax.js file-
$('#save_button').click(function() {
var street = $('#address').val();
var city = $('#city').val();
$.ajax({
type: "POST",
url: "${createLink(controller: 'property', action: 'save')}",
data: { address: street, city: city },
success: function(data) {
alert(data);
}
});
});
And here is the code in my property controller(save action)-
def save = {
def propertyInstance = new Property(params)
if (propertyInstance.save(flush: true)) {
flash.message = "Property successfully added."
redirect(controller:"user", action: "show", id:params.owners.id)
}
else {
render(view: "create", model: [propertyInstance: propertyInstance, id:params.owners.id])
}
}
What am I doing wrong here? I am not at all familiar with Ajax, so sorry if its an obvious mistake.. please help.
$('#address').val(); and $('#city').val(); will get you the value of the first #address or #city element jQuery finds. If you want to make, let's say, an array for all the address and city values provided you could do this:
var cities = [];
var addresses = [];
$('#address​​​​').each(function() {
addresses.push($(this).val());
});​
$('#cities​​​​').each(function() {
cities.push($(this).val());
});​
If there's two address and city inputs on the page, the result will look something like this:
console.log(addresses); // [address1, address2]
console.log(cities); // [city1, city2]
Edit: To reset the fields on submission (or "add" if you change the jQuery selector), you could do this:
$('#save_button').click(function() {
// ... all your regular ajax stuff ...
// reset the fields
$('#address').val('');
$('#city').val('');
// ... and so on until you reset all fields
});

Categories

Resources