JQuery form submission not working with API - javascript

I am trying to retrieve date from a form submission to use in a SmartyStreet API request. It's not outputting the response from the API.
HTML:
<div class="form-style-5">
<form id="myForm">
<fieldset>
<legend><span class="number">1</span> Input Address</legend>
<input type="text" id="street" name="street" placeholder="Street">
<input type="text" id="city" name="city" placeholder="City">
<input type="text" id="state" name="state" placeholder="State">
<input type="submit" value="Submit" />
</fieldset>
</form>
<fieldset>
<legend><span class="number">2</span> Results</legend>
<div id='resultBox'>
</div>
</fieldset>
</div>
JS:
AUTH_ID = "123456789";
AUTH_TOKEN = "123456789"
$("myForm").submit(function(event) {
street = $("#street").val()
city = $("#city").val()
state = $("#state").val()
var xhr = new XMLHttpRequest();
xhr.open("get", "https://us-street.api.smartystreets.com/street-address?street=" + street + "&auth-id=" + AUTH_ID + "&auth-token=" + AUTH_TOKEN, true);
xhr.send();
var addresses = JSON.parse(xhr.responseText);
console.log('Hello')
$( "#resultBox" ).text(addresses).show();
event.preventDefault();
});
Any help is appreciated, I just want to know why it isn't working and if there is a better way. Thanks

You can use the onreadystatechange property to monitor the state of your request,when the state changes the function gets called, when the status of the request is 4 (Completed) and Response status code is 200 (OK), then you change the address text using the returned json data from the response text property. I hope this helps.
$("myForm").submit(function(event) {
event.preventDefault();
street = $("#street").val()
city = $("#city").val()
state = $("#state").val()
var xhr = new XMLHttpRequest();
xhr.open("get", "https://us-street.api.smartystreets.com/street-address?street=" + street + "&auth-id=" + AUTH_ID + "&auth-token=" + AUTH_TOKEN, true);
xhr.send();
var addresses;
xhr.onreadystatechange = function() {//Call a function when the state changes.
if(xhr.readyState == 4 && xhr.status == 200) {
addresses = JSON.parse(xhr.responseText);
$( "#resultBox" ).text(addresses).show();
console.log('Hello');
}
}
});

Try below code. Use document.ready function
<script>
AUTH_ID = "123456789";
AUTH_TOKEN = "123456789"
$(document).ready(function(){
$("#myForm").submit(function(event) {
street = $("#street").val()
city = $("#city").val()
state = $("#state").val()
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var addresses = JSON.parse(xhr.responseText);
console.log(xhr.responseText)
$( "#resultBox" ).text(addresses).show();
}
};
xhr.open("get", "https://us-street.api.smartystreets.com/street-address?street=" + street + "&auth-id=" + AUTH_ID + "&auth-token=" + AUTH_TOKEN, true);
xhr.send();
event.preventDefault();
});
});
</script>

Related

Why am I getting an array for $_POST['variable'] from an AJAX login form submission

I'm learning AJAX following the tutorials at https://www.w3schools.com/xml/ajax_intro.asp. I have succeffully completed a couple of GET requests, I'm now attempting a POST request.
My form:
<input class="form-control" type="email" id="log_email" required name="log_email">
<input class="form-control" type="password" id="log_password" required name="log_password">
<a class="btn" onclick="login(this)" >Log in</a>
My Ajax:
<script type="text/javascript">
function login(this_record) {
var xhttp = new XMLHttpRequest();
var UsrEml = $('#log_email').val();
var UsrPw = $("#log_password").val();
var AjaxURL = ("ajax_login.php") ;
var AjaxPost = ("eml=" + UsrEml + "&pw=" + UsrPw);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("accountstuff").innerHTML = this.responseText;
}
};
xhttp.open("POST", AjaxURL, true);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send(AjaxPost);
}
</script>
My PHP:
<?php
echo ($_POST["eml"]) ;
?>
The result is:
Array
(
[eml] => test#user.com
[pw] => Password1
)
I was expecting:
test#user.com
Why am I getting an array for a $_POST variable?

XMLHttpRequest with Javascript and HTML5

How do you insert the correct "xhr" value into the HTML5 button?
I am not sure how this whole XMLHttpRequest works. I believe it takes: xml data, text, numbers or null from the HTML5 button input and prints it out in text input in this case but can it store a value in it to call on it later. That is the question!
<script type="text/javascript">
function readBody(xhr) {
var data;
if (!xhr.responseType || xhr.responseType === "text"){
data = xhr.responseText;
} else if (xhr.responseType === "document") {
data = xhr.responseXML;
} else {
data = xhr.response;
}
window.document.myform.xhr1.value = data;
return data;
}
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200); {
window.document.myform.readBodyxhr.value = readBody(xhr);
}
else {
alert(xhr.status);
}
xhr.open('GET', 'http://www.google.com', true);
xhr.send(null);
}
</script>
...HTML5
<input type="button" name="XMLHttpRequest" value="XMLHttpRequest" onclick="readBody(xhr)" />
<input type="text" name="xhr1" value="" size="4"/></td>
<input type="text" name="readBodyxhr" value="" size="4"/></td>
Move call to .open() and .send() outside of onreadystatechange handler.
Substituted onload and onerror for onreadystatechange. ; following if condition is a syntax error. Note also, XMLHttpRequest with true passed at third parameter at .open() sets load handler to return results asynchronously.
<script type="text/javascript">
var url = "https://gist.githubusercontent.com/guest271314/6a76aa9d2921350c9d53/raw/1864137bfd2eb62705bd0e71175048a28b3253e6/abc.txt";
function readBody() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
window.document.myform
.readBodyxhr.value = xhr.responseText;
}
xhr.onerror = function() {
alert(xhr.status);
}
xhr.open("GET", url, true);
xhr.send(null);
}
</script>
...HTML5
<form name="myform">
<input type="button" name="XMLHttpRequest" value="XMLHttpRequest" onclick="readBody()" />
<input type="text" name="xhr1" value="" size="4" />
<input type="text" name="readBodyxhr" value="" size="4" />
</form>

AJAX works in jQuery but not in vanilla JS

I have a small form where when the username field is being blurred or out of focus, AJAX checks if the entered username is already recorded in the database. The problem is that the AJAX in jQuery works, but not in vanilla JS. I need to know what line or part of my code did I get it wrong.
HTML
<form action="process.php" method="post">
<input class="username" type="text" name="username" placeholder="Enter username" autocomplete="off">
<span class="uname_notice"></span><br>
<input type="submit" value="Submit">
</form>
jQuery
$('.username').blur(function() {
var username = $(this).val();
$.ajax({
url: 'process.php',
type: 'post',
data: {username: username},
success: function(responseText) {
$('.uname_notice').text(responseText);
}
})
});
Vanilla JS
document.querySelector('.username').onblur = function() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "process.php", true);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
document.querySelector('.uname_notice').textContent = xhr.responseText;
}
}
xhr.send();
}
Send data along with the HTTP request.
document.querySelector('.username').onblur = function() {
var xhr = new XMLHttpRequest();
var data = new FormData();
var username = document.getElementsByClassName('username')[0].value;
data.append('username', username);
xhr.open("POST", "process.php", true);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
document.querySelector('.uname_notice').textContent = xhr.responseText;
}
}
xhr.send(data);
}
You forgot to specify post value. Try to use this:
document.querySelector('.username').onblur = function() {
var params = 'username='+this.value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "process.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xhr.setRequestHeader("Content-length", params.length);
xhr.setRequestHeader("Connection", "close");
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
document.querySelector('.uname_notice').textContent = xhr.responseText;
}
};
xhr.send(params);
};

onreadystatechange not submit forms or it always submits forms

I want my input email address to be checked on registration page. I am right now using onreadystatechange to get the response from database with responseText. If responseText is true, then do not submit the form, otherwise, submit.
However, my code will always submit my forms even if the condition is true.
//////////////HTML file//////////////////
<form action="regist.php" method="post" id="submitForm">
<label>*Email:</label>
<label class="validate" id="emailError">XXXX#XXXX.XXX</label></br>
<input type="text" id="email" name="email"/></br>
<label>*First Name:</label>
<label class="validate" id="firstnameError">Letters only!</label>
<input type="text" id="firstname" name="firstname"/></br>
<label>Last Name:</label>
<input type="text" id="lastname" name="lastname"/></br>
<label>*Password:</label>
<label class="validate" id="passwordError">at least 6 characters!</label>
<input type="password" id="password" name="password"/></br>
<label class="validate" id="used">Email has been used!</label></br>
<button id="Validate">Register</button>
</form>
////////////////////JS file////////////////
$(document).ready(function () {
$("#regi").click(function () {
var popup = $("#register").dialog({modal: true});
popup.show();
});
$("#Validate").click(function () {
validate();
});
});
function validate() {
var email = document.getElementById("email").value;
var error = $("#used");
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "backend.php?req=checkDuplicate&user=" + email, true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText == 1) {//check if email existed in db, return 1
error.show();
console.log("find match! Do not proceed!!");
$('#submitForm').submit(false);
}
else {
error.hide();
console.log("Redirect");
$('#submitForm').submit(true);//only here should do redirect
}
}
}
xmlhttp.send();
}
First of all, you should read some documentation about jQuery submit.
function validate() {
var email = document.getElementById("email").value;
var error = $("#used");
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "backend.php?req=checkDuplicate&user=" + email, true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText == 1) {//check if email existed in db, return 1
error.show();
console.log("find match! Do not proceed!!");
// if you don't want to proceed just don't call submit !
// $('#submitForm').submit(false);
}
else {
error.hide();
console.log("Redirect");
//$('#submitForm').submit(true);//only here should do redirect
// remove the true value using jQuery to trigger the submit
$('#submitForm').submit();
}
}
}
xmlhttp.send();
}
Using jQuery.get you can have same result with that :
function validate() {
var email = $("#email").val();
var error = $("#used");
var url = "backend.php?req=checkDuplicate&user=" + email;
$.get(url , function( data ){
if(data===1){
error.show();
console.log("find match! Do not proceed!!");
}else{
error.hide();
console.log("Redirect");
$('#submitForm').submit()
}
});
}
I hope this will help you.

Simple ajax form using javascript no jQuery

I'm working with a form for which the mark-up I can't change & can't use jQuery.
Currently the form post the results to a new window. Is it possible to change this to an ajax form so that the results displays on submit instead without altering any mark-up?
Pulling the results (mark-up) from the results page back to the form page.
Here is the mark-up for the form.
<form class="form-poll" id="poll-1225962377536" action="/cs/Satellite" target="_blank">
<div class="form-item">
<fieldset class="form-radio-group">
<legend><span class="legend-text">What mobile phone is the best?</span></legend>
<div class="form-radio-item">
<input type="radio" class="radio" value="1225962377541" name="option" id="form-item-1225962377541">
<label class="radio" for="form-item-1225962377541">
<span class="label-text">iPhone</span>
</label>
</div><!-- // .form-radio-item -->
<div class="form-radio-item">
<input type="radio" class="radio" value="1225962377542" name="option" id="form-item-1225962377542">
<label class="radio" for="form-item-1225962377542">
<span class="label-text">Android</span>
</label>
</div><!-- // .form-radio-item -->
<div class="form-radio-item">
<input type="radio" class="radio" value="1225962377543" name="option" id="form-item-1225962377543">
<label class="radio" for="form-item-1225962377543">
<span class="label-text">Symbian</span>
</label>
</div><!-- // .form-radio-item -->
<div class="form-radio-item">
<input type="radio" class="radio" value="1225962377544" name="option" id="form-item-1225962377544">
<label class="radio" for="form-item-1225962377544">
<span class="label-text">Other</span>
</label>
</div><!-- // .form-radio-item -->
</fieldset>
</div><!-- // .form-item -->
<div class="form-item form-item-submit">
<button class="button-submit" type="submit"><span>Vote now</span></button>
</div><!-- // .form-item -->
<input type="hidden" name="c" value="News_Poll">
<input type="hidden" class="pollId" name="cid" value="1225962377536">
<input type="hidden" name="pagename" value="Foundation/News_Poll/saveResult">
<input type="hidden" name="site" value="themouth">
Any tips/tutorial is much appreciated. :)
The following is a far more elegant solution of the other answer, more fit for modern browsers.
My reasoning is that if you need support for older browser you already most likely use a library like jQuery, and thus making this question pointless.
/**
* Takes a form node and sends it over AJAX.
* #param {HTMLFormElement} form - Form node to send
* #param {function} callback - Function to handle onload.
* this variable will be bound correctly.
*/
function ajaxPost (form, callback) {
var url = form.action,
xhr = new XMLHttpRequest();
//This is a bit tricky, [].fn.call(form.elements, ...) allows us to call .fn
//on the form's elements, even though it's not an array. Effectively
//Filtering all of the fields on the form
var params = [].filter.call(form.elements, function(el) {
//Allow only elements that don't have the 'checked' property
//Or those who have it, and it's checked for them.
return typeof(el.checked) === 'undefined' || el.checked;
//Practically, filter out checkboxes/radios which aren't checekd.
})
.filter(function(el) { return !!el.name; }) //Nameless elements die.
.filter(function(el) { return el.disabled; }) //Disabled elements die.
.map(function(el) {
//Map each field into a name=value string, make sure to properly escape!
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
}).join('&'); //Then join all the strings by &
xhr.open("POST", url);
// Changed from application/x-form-urlencoded to application/x-form-urlencoded
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//.bind ensures that this inside of the function is the XHR object.
xhr.onload = callback.bind(xhr);
//All preperations are clear, send the request!
xhr.send(params);
}
The above is supported in all major browsers, and IE9 and above.
Here's a nifty function I use to do exactly what you're trying to do:
HTML:
<form action="/cs/Satellite">...</form>
<input type="button" value="Vote now" onclick="javascript:AJAXPost(this)">
JS:
function AJAXPost(myself) {
var elem = myself.form.elements;
var url = myself.form.action;
var params = "";
var value;
for (var i = 0; i < elem.length; i++) {
if (elem[i].tagName == "SELECT") {
value = elem[i].options[elem[i].selectedIndex].value;
} else {
value = elem[i].value;
}
params += elem[i].name + "=" + encodeURIComponent(value) + "&";
}
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("POST",url,false);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length", params.length);
xmlhttp.setRequestHeader("Connection", "close");
xmlhttp.send(params);
return xmlhttp.responseText;
}
Nowadays using FormData is the easiest method. You construct it with a reference to the Form element, and it serializes everything for you.
MDN has an example of this here -- roughly:
const form = document.querySelector("#debarcode-form");
form.addEventListener("submit", e => {
e.preventDefault();
const fd = new FormData(form);
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", e => {
console.log(e.target.responseText);
});
xhr.addEventListener("error", e => {
console.log(e);
});
xhr.open("POST", form.action);
xhr.send(fd);
});
and if you want it as an object (JSON):
const obj = {};
[...fd.entries()].forEach(entry => obj[entry[0]] = entry[1]);
Expanding on Madara's answer: I had to make some changes to make it work on Chrome 47.0.2526.80 (not tested on anything else). Hopefully this can save someone some time.
This snippet is a modification of that answer with the following changes:
filter !el.disabled,
check type of input before excluding !checked
Request type to x-www-form-urlencoded
With the following result:
function ajaxSubmit(form, callback) {
var xhr = new XMLHttpRequest();
var params = [].filter.call(form.elements, function (el) {return !(el.type in ['checkbox', 'radio']) || el.checked;})
.filter(function(el) { return !!el.name; }) //Nameless elements die.
.filter(function(el) { return !el.disabled; }) //Disabled elements die.
.map(function(el) {
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
}).join('&'); //Then join all the strings by &
xhr.open("POST", form.action);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = callback.bind(xhr);
xhr.send(params);
};
The strategy is to serialise the form and send the data using XHR, then do what you want with the response. There is a good set of utilities and help at Matt Krus's Ajax Toolbox and related Javascript Toolbox.
If you are just serialising the form posted, then the following will do the trick. It can easily be extended to include other form control types:
var serialiseForm = (function() {
// Checkboxes that have already been dealt with
var cbNames;
// Return the value of a checkbox group if any are checked
// Otherwise return empty string
function getCheckboxValue(cb) {
var buttons = cb.form[cb.name];
if (buttons.length) {
for (var i=0, iLen=buttons.length; i<iLen; i++) {
if (buttons[i].checked) {
return buttons[i].value;
}
}
} else {
if (buttons.checked) {
return buttons.value;
}
}
return '';
}
return function (form) {
var element, elements = form.elements;
var result = [];
var type;
var value = '';
cbNames = {};
for (var i=0, iLen=elements.length; i<iLen; i++) {
element = elements[i];
type = element.type;
// Only named, enabled controls are successful
// Only get radio buttons once
if (element.name && !element.disabled && !(element.name in cbNames)) {
if (type == 'text' || type == 'hidden') {
value = element.value;
} else if (type == 'radio') {
cbNames[element.name] = element.name;
value = getCheckboxValue(element);
}
}
if (value) {
result.push(element.name + '=' + encodeURIComponent(value));
}
value = '';
}
return '?' + result.join('&');
}
}());
A modern way using fetch would be:
const formData = new FormData(form);
fetch(form.action, {
method: 'POST',
body: formData
});
Note browser support and use this polyfil if IE-support is needed
function ajaxSubmit(form, callback) {
var xhr = new XMLHttpRequest();
var params = [].filter.call(form.elements, function (el) {return !(el.type in ['checkbox', 'radio']) || el.checked;})
.filter(function(el) { return !!el.name; }) //Nameless elements die.
.filter(function(el) { return !el.disabled; }) //Disabled elements die.
.map(function(el) {
if (el.type=='checkbox') return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.checked);
else return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
}).join('&'); //Then join all the strings by &
xhr.open("POST", form.action);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onload = callback.bind(xhr);
xhr.send(params);
};
I just took Coomie's answer above and made it work for Radio/Checkboxes. I can't believe how simple and clear this is. With a few exceptions, I'm done using frameworks.
var params = "";
var form_elements = form.elements;
for (var i = 0; i < form_elements.length; i++)
{
switch(form_elements[i].type)
{
case "select-one":
{
value = form_elements[i].options[form_elements[i].selectedIndex].value;
}break;
case "checkbox":
case "radio":
{
if (!form_elements[i].checked)
{
continue; // we don't want unchecked data
}
value = form_elements[i].value;
}break;
case "text" :
{
value = form_elements[i].value;
}break;
}
params += encodeURIComponent(form_elements[i].name) + "=" + encodeURIComponent(value) + "&";
}
var xhr = new XMLHttpRequest();
xhr.open('POST', "/api/some_url");
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200)
{
console.log("xhr.responseText");
}
else
{
console.log("Error! Status: ", xhr.status, "Text:", xhr.responseText);
}
}
};
console.log(params);
xhr.send(params);
Here's the simplest method I came up with. I haven't found an example that uses this exact approach. The code submits the form using a non-submit type button and places the results into a div, if the form is not valid (not all required fields filled), it will ignore the submit action and the browser itself will show which fields are not filled correctly.
This code only works on modern browsers supporting the "FormData" object.
<script>
function ajaxSubmitForm() {
const form = document.getElementById( "MyForm" );
if (form.reportValidity()) {
const FD = new FormData( form );
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("content_area").innerHTML = this.responseText; } };
xhttp.open("POST","https://example.com/whatever.php",true);
xhttp.send( FD );
}
}
</script>
<div id="content_area">
<form id="MyForm">
<input type="hidden" name="Token" Value="abcdefg">
<input type="text" name="UserName" Value="John Smith" required>
<input type="file" accept="image/jpeg" id="image_uploads" name="ImageUpload" required>
<button type="button" onclick="ajaxSubmitForm()">
</form>
</div>

Categories

Resources