Scraping a webpage with cheerio - javascript

I am trying to scrape a webpage with cheerio, but my request is being blocked with some sort of bot-detecting software. The response looks like this:
<body>
<div class="content">
...
<div class="main">
<h1>Suspicious activity detected</h1>
<div class="box">
<p>Due to suspicious activity from your computer, we have blocked your access to http://www.something.com. After completing the form, your information will be evaulauted and you may be unblocked. </p>
<p><span>Note</span>: This website may require JavaScript. If you have JavaScript disabled, please enable it before attempting to return to http://www.something.com.</p>
<div class="block">
<form id="distilUnblockForm" method="post" action="http://verify.distil.it/distil_blocked.php">
<div id="dUF_first_name">
<label for="dUF_input_first_name">First Name:</label>
<input type="text" id="dUF_input_first_name" name="first_name" value="" />
</div>
<div id="dUF_last_name">
<label for="dUF_input_last_name">Last Name:</label>
<input type="text" id="dUF_input_last_name" name="last_name" value="" />
</div>
<div id="dUF_email">
<label for="dUF_input_email">E-mail:</label>
<input type="text" id="dUF_input_email" name="email" value="" />
</div>
<div id="dUF_city" style="display: none">
<label for="dUF_input_city">City (Leave Blank):</label>
<input type="text" id="dUF_input_city" name="city" value="" />
</div>
<div id="dUF_unblock">
<input id="dUF_input_unblock" name="unblock" type="submit" value="Request Unblock" />
</div>
<div id="dUF_unblock_text">
You reached this page when attempting to access https://someWebsite from myIPAddress on someDateInISOFormat.
</div>
<div id="dUF_form_fields" style="display: none">
<input type="hidden" name="B" value="someNumbersAndLetters" />
<input type="hidden" name="P" value="someMoreNumbersAndLetters" />
<input type="hidden" name="I" value="" />
<input type="hidden" name="U" value="" />
<input type="hidden" name="V" value="###" />
<input type="hidden" name="O" value="" />
<input type="hidden" name="D" value="###" />
<input type="hidden" name="A" value="###" />
<input type="hidden" name="LOADED" value="someDate" />
<input type="hidden" name="Q" value='someUrl' />
<input type="hidden" id="distil_block_identity_info" name="XX" value="" />
</div>
</form>
...
</body>
I am thinking I can get around this by added a callback with a post function, but it doesn't seem to be working. My code is below:
var url = someUrl;
request(url, function (error, response, html) {
console.log("html", html); //where i am getting the above html
request.post({
uri: 'hhttp://verify.distil.it/distil_blocked.php',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: require('querystring').stringify(credentials)
}, function(err, res, body){
if(err) {
callback.call(null, new Error('Login failed'));
return;
} else {
var $ = cheerio.load(html);
var parsedResults = [];
$('#someSelector').each(function(i, element){
var node = $(this).children();
// Get all the children
var something = $(node).eq(0).text();
var anotherThing = $(node).eq(1).text();
var oneMoreThing = $(node).eq(2).text();
// Make it into an object
var metadata = {
something: something,
anotherThing: anotherThing,
oneMoreThing: oneMoreThing
};
// Push meta-data into parsedResults array
parsedResults.push(metadata);
});
// Log our finished parse results in the terminal
console.log(parsedResults);
}
});
});
This is failing on the post request, I am not sure if it is because I am doing the callback wrong or if the post request is not a valid way to work around the bot. Any help is greatly appreciated, thanks.

I realized I was having issues because cheerio does not load javacsript. The site I was trying to scrape loads data with javacsript, so I need to use a different tool. Probably will use (PhantomJS)[http://phantomjs.org/].

You should try setting your headers as browser-like as you can. For instance, you are not setting your user-agent, cache-control, accept, etc. That makes it dead simple for the site to detect you are not a browser.
Check the header on a normal request (on Chrome use More Tools-> Developer Tools, network and select the HTML file. More info on this thread) and send yours as similar to those as you can.

Related

web data capture .NET server

I'm trying to do a data extraction from a .NET web server but I cannot send the data correctly.
If I post the data with a normal html form I can show the correct page with the information I need.
The html form contains valid fields as __VIEWSTATE, __EVENTVALIDATION and other fields to query the server.
This form works fine but I cannot capture any data.
If I try to send the same data (with the POST method) using javascript with ActiveXObject("Msxml2.XMLHTTP.3.0"); or using Server.CreateObject("MSXML2.ServerXMLHTTP") in classic ASP, I receive in return from the server the message:
''The state information is invalid for this page and might be corrupted.,, or the correct page w/o the result of the query (page empty).
I think the problem is in the header, so I've tried to send in many formats but w/o success.
Any help ?
the following is the code that correctly send data
<form name="aspnetForm" method="post" action="http://geon....neNew.aspx" id="aspnetForm">
<input type="text" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="text" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />`enter code here`
<input type="text" name="__VIEWSTATE" id="__VIEWSTATE" value="/--------- here the key --"/>
<input type="text" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/--------- here the key --" />
<br>
DUG:
<input name="ctl00$ContentPlaceHolder1$txtDUG" type="text" id="ctl00_ContentPlaceHolder1_txtDUG" <td id="ctl00_ContentPlaceHolder1_TableCell3">
<br>
Denomin.:
<input name="ctl00$ContentPlaceHolder1$txtDenominazione" type="text" value="indipendenza" id="ctl00_ContentPlaceHolder1_txtDenominazione" >
<br>
Civico:
<input name="ctl00$ContentPlaceHolder1$txtCivico" type="text" value="34" id="ctl00_ContentPlaceHolder1_txtCivico" />
<br>
Espon:
<input name="ctl00$ContentPlaceHolder1$txtEsponente" type="text" id="ctl00_ContentPlaceHolder1_txtEsponente" >
<br>
CAP:
<input name="ctl00$ContentPlaceHolder1$txtCAP" type="text" maxlength="5" id="ctl00_ContentPlaceHolder1_txtCAP" >
<br>Prov.:
<input name="ctl00$ContentPlaceHolder1$txtSiglaProv" type="text" id="ctl00_ContentPlaceHolder1_txtSiglaProv" />
<br>
Comune:
<input name="ctl00$ContentPlaceHolder1$txtComune" type="text" value="gazzo" id="ctl00_ContentPlaceHolder1_txtComune" >
<b>Informazioni addizionali</b></p>
<input id="ctl00_ContentPlaceHolder1_chkUffRecapito" type="checkbox" name="ctl00$ContentPlaceHolder1$chkUffRecapito" tabindex="9" />
<label for="ctl00_ContentPlaceHolder1_chkUffRecapito">Centro/Presidio decentrato di distribuzione</label>
<br>
<input id="ctl00_ContentPlaceHolder1_chkCodPre" type="checkbox" name="ctl00$ContentPlaceHolder1$chkCodPortalettere" tabindex="10" />
<label for="ctl00_ContentPlaceHolder1_chkCodPre">Numero Potere</label>
<br>
<input id="ctl00_ContentPlaceHolder1_chkAmbigui" type="checkbox" name="ctl00$ContentPlaceHolder1$chkAmbigui" tabindex="11" />
<label for="ctl00_ContentPlaceHolder1_chkAmbigui">Scarta in caso di indirizzi ambigui</label>
<br>
<input type="submit" name="ctl00$ContentPlaceHolder1$cmdNormalizza" value="Normalizza" id="ctl00_ContentPlaceHolder1_cmdNormalizza" />
<br>
</form>
</body>
</html>
---- and this is the code that capture the data in the form but send data incorrectly:
<script>
var req1 = new XMLHttpRequest();
req1.open('GET', document.location, false);
req1.send(null);
var headers = req1.getAllResponseHeaders().toLowerCase();
//alert(headers);
document.write(headers+'<p>');
var formElements=document.getElementById("aspnetForm").elements;
var postData={};
var qs;
qs="";
for (var i=0; i<formElements.length; i++) {
if (formElements[i].type!="submit")
{
qs=qs + formElements[i].name + "=" + formElements[i].value + "&" ;
// alert(formElements[i].name);
}
}
//qs = qs.substring(0, qs.length - 1);
qs=qs +"ctl00$ContentPlaceHolder1$cmdNormalizza=Normalizza"
document.write(qs);
var req = new ActiveXObject("Msxml2.XMLHTTP.3.0");
req.open('POST', 'http://geono....LineNew.aspx', false);
//req.open('POST', 'http://vepdcm1sa01/exps/x2/read.asp', false);
//req.setRequestHeader('Content-Type', 'text/plain;');
req.setRequestHeader('cache-control','private');
//req.setRequestHeader('content-length','162107');
req.setRequestHeader('content-type','text/plain');
req.setRequestHeader('server','microsoft-iis/7.5');
//req.setRequestHeader('date',' tue, 19 feb 2019 10:17:55 gmt');
req.send(qs);
if(req.status == 200)
document.write(req.responseText);
</script>

Save Data to Localstorage and use it to populate fields after submit

I have optin popup of two steps, first step is to capture email and name, when user click submit the data is captured, and another popup appears, the new popup has a form with more fields to get more info, plus email and name field.
what I want to do is to automatically populate the email and name field from first popup and hide them with display:none so user can't see them, after submit the data is captured again (all goes to activecampaign).
the two forms works just fine, what is not working is saving the data and calling it when needed
here is the js I'm using
jQuery(function($){
// PART I: Saving user details locally
$('#arlington-field-submit').on('click', function(){
// check if the user's browser has localStorage support
if (typeof(Storage) !== "undefined") {
// Code for localStorage/sessionStorage.
// store the full name in localStorage
var fullname = document.querySelector("input[name=arlington-name]");
localStorage.user_name = fullname.value;
// save the email in localStorage
var email = document.querySelector("input[name=arlington-email]");
$("input[name=fullname]").val(localStorage.getItem("server"));
localStorage.user_email = email.value;
}
});
// PART II: Pre-filling forms forms with locally saved values
if (typeof(Storage) !== "undefined") {
// check if the user has a name field stored
if (localStorage.user_name) {
name_field = document.querySelector("._form input[name=fullname]");
name_field.value = localStorage.user_name;
}
// check if the user has an email field stored
if (localStorage.user_email) {
email_field = document.querySelector("._form input[name=email]");
email_field.value = localStorage.user_email;
}
}
});
first form html:
<div id="arlington-element-form" class="arlington-element-form arlington-element" data-element="form">
<div id="arlington-form" class="arlington-form arlington-has-name-email arlington-has-buttons">
<div class="arlington-form-wrap"><input id="arlington-field-comments" name="arlington-comments" type="text" data-selectable="true" data-target="#builder-setting-comments_value" class="arlington-field-comments" placeholder="" value="" style="" autocomplete="off"><input id="arlington-field-name" name="arlington-name" type="text" data-selectable="true" data-target="#builder-setting-name_value" class="arlington-field-name" placeholder="Enter your name here..." value="">
<input id="arlington-field-email" name="arlington-email" type="email" data-selectable="true" data-target="#builder-setting-email_value" class="arlington-field-email" placeholder="Enter your email address here..." value="" >
<input id="arlington-field-submit" name="arlington-submit" type="submit" data-selectable="true" data-target="#builder-setting-submit_value" class="arlington-field-submit" value="JOIN NOW" >
</div>
<div class="arlington-yesno-wrap">
<button id="arlington-button-yes" type="button" name="arlington-yes" data-selectable="true" data-target="#builder-setting-yes_value" data-action="form" data-type="yes" class="arlington-button-yes arlington-button-yesno">Submit!</button>
</div></div></div>
second form html:
<form method="POST" action="xxxxxx" id="_form_8_" class="_form _form_8 _inline-form _dark" novalidate> <input type="hidden" name="u" value="8" /> <input type="hidden" name="f" value="8" /> <input type="hidden" name="s" /> <input type="hidden" name="c" value="0" /> <input type="hidden" name="m" value="0" /> <input type="hidden" name="act" value="sub" /> <input type="hidden" name="v" value="2" />
<div class="_form-content">
<div class="_form_element _x72304349 _full_width "> <label class="_form-label"> Full Name </label>
<div class="_field-wrapper"> <input type="text" name="fullname" placeholder="Type your name" /> </div>
</div>
<div class="_form_element _x10201592 _full_width "> <label class="_form-label"> Email* </label>
<div class="_field-wrapper"> <input type="text" name="email" placeholder="Type your email" required/> </div>
</div>
<div class="_form_element _x29901314 _full_width "> <label class="_form-label"> Phone </label>
<div class="_field-wrapper"> <input type="text" name="phone" placeholder="Type your phone number" /> </div>
</div>
<div class="_button-wrapper _full_width"> <button id="_form_8_submit" class="_submit" type="submit"> Submit </button> </div>
<div class="_clear-element"> </div>
</div>
</form>
Since the input which is being clicked is a submit button, chances are that the page is navigating before the JS within the click handler gets a chance to fire.
Try and replace
$('#arlington-field-submit').on('click', function(){
with:
$('#_form_8_').on('submit', function(event){
Then you can prevent the form from actually submitting so your JS can run:
$('#_form_8_').on('submit', function(event){
event.preventDefault();
// Do localStorage stuff
$(this).submit(); // submit the form normally after localStorage is saved
});
The way you look for elements is wrong, because you forgot quotes wrapping attribute values:
var fullname = document.querySelector("input[name=arlington-name]");
should be:
var fullname = document.querySelector('input[name="arlington-name"]');
And so on...
BTW I'm surprised you don't report an error like "An invalid or illegal string was specified".

BrainTree Hosted Fields onPaymentMethodReceived function not working returning nonce

I am having a hard time figuring out why the onPaymentMethodReceived in a hosted fields is not returning any values.
`
<form action="" id="my-form" method="post">
<label for="a">Amount</label>
<div id="amount">
<input type="text" name="amount" value="400" id="amount" />
</div>
<label for="card-number">Card Number</label>
<div id="card-number">
<input type="text" name="cardNumber" value="4111111111111111" id="cardNumber" />
</div>
<label for="cvv">CVV</label>
<div id="cvv">
<input type="text" name="CVV" value="020" id="cv-v" />
</div>
<label for="expiration-month">Expiration Month</label>
<div id="expiration-month">
<input type="text" name="expirMonth" value="10" id="expirMonth" />
</div>
<label for="expiration-year">Expiration Year</label>
<div id="expiration-year">
<input type="text" name="expirYear" value="20" id="expirYear" />
</div>
<input type="submit" value="Pay" id="btn_submit"/>
</form>
<script>
var nonce0 ;
braintree.setup(clientToken, "custom",
{
id: "my-form",
hostedFields: {
number: {
selector: "#card-number"
},
cvv: {
selector: "#cvv"
},
expirationMonth: {
selector: "#expiration-month"
},
expirationYear: {
selector: "#expiration-year"
},
},
onPaymentMethodReceived:function(nonce){
console.log("in onPaymentMethodReceived");
console.log(nonce);
nonce0 = nonce;
alert('OnPaymentMR');
console.log(JSON.stringify(nonce));
return false;
},
onError :function(obj){
alert('onError');
console.log(JSON.stringify(obj));
}
});
console.log('BTree = '+ nonce0);
</script>
`
I wanted to store the nonce returned but nothing is happening, console.log is not showing any values. Even the onError is not doing anything either.
Using breakpoints,I can tell that the hidden nonce is coming back but the callback function is not getting fired.
I tried it with the Dropin-UI and it does work and I can get the nonce from the onPaymentMethodReceived.
Not sure what I am doing wrong.
Full disclosure: I work as a developer for Braintree
When using Hosted Fields, the form should only include a div container for each payment field. Your implementation would look something like this:
<form action="" id="my-form" method="post">
<label for="a">Amount</label>
<div id="amount"></div>
<label for="card-number">Card Number</label>
<div id="card-number"></div>
<label for="cvv">CVV</label>
<div id="cvv"></div>
<label for="expiration-month">Expiration Month</label>
<div id="expiration-month"></div>
<label for="expiration-year">Expiration Year</label>
<div id="expiration-year”></div>
<input type="submit" value="Pay" id="btn_submit"/>
</form>
The Braintree setup script will then render iframes to handle payment field inputs. If you continue to have issues, you can always get in touch with Braintree support.
In "onPaymentMethodReceived" method you need to try "nonce.nonce" var to check nonce in responce.
Like -
onPaymentMethodReceived:function(obj) {
var nonce_from_braintree = obj.nonce
}
Also you can check below link to get more detailed script to manipulate braintree payment gateway integration with hosted field.
http://www.ilovephp.net/php/simple-braintree-paypal-payment-gateway-integration-in-php-with-demo-examples/
Hope this helps you...:)

"Data entered successfully" message to appear on same page of insert form?

I have an insert form where I can submit data into my database.
Here's my code:
<form action="insert_backend.php" method="POST" enctype="multipart/form-data">
<!-- Method can be set as POST for hiding values in URL-->
<h2>Form</h2>
<label for="uploadedimage">Small image to upload: </label>
<input type="file" name="uploadedimage" id="uploadedimage"/><br />
<label>Date:</label>
<input class="input" name="date" type="text" value=""><br />
<label>Retrace:</label>
<input class="input" name="retrace" type="text" value=""><br />
<label>Start of Swing Trade:</label>
<input class="input" name="start_of_swing_trade" type="text" value=""><br />
<label>End of Swing Trade:</label>
<input class="input" name="end_of_swing_trade" type="text" value=""><br />
<label>Bull flag:</label>
<input class="input" name="bull_flag" type="text" value=""><br />
<label>Bear flag:</label>
<input class="input" name="bear_flag" type="text" value=""><br />
<label>EMA Crossover:</label>
<input class="input" name="ema_crossover" type="text" value=""><br />
<label>Trading Instrument:</label>
<input class="input" name="trading_instrument" type="text" value=""><br />
<input class="submit" name="submit" type="submit" value="Insert">
</form>
Here's a snippet of the "Success" message on the php that is used to process the data submitted to the database:
$stmt->bind_param('sssssssss',$target_path, $date, $retrace, $start_of_swing_trade, $end_of_swing_trade, $bull_flag, $bear_flag, $ema_crossover, $trading_instrument);
if(!$stmt){ exit("bind failed");}
//will return 0 if fail
if($stmt->execute() != 0){
echo "New record created successfully";
}else{ echo "Failed to insert new record";}
Whenever I Insert data, I get the "New record created successfully" message on the insert_backend.php page, which is the php file used to process and submit the data, but not on the actual form page used to insert data. Usually when you use a form to send a message to someone or to send data into a database, the form resets itself and you get a "success" message that shows at the bottom of the form without getting redirected to another page. But the code I have redirects me to the page that is used to process the data. how do I get it to show the "success" message on the same page as the form itself?
My FULL insert form code (with the php redirect check solution in it):
<!DOCTYPE html>
<html>
<head>
<title>Chart Submission Form</title>
<link href="insert.css" rel="stylesheet">
</head>
<body>
<div class="maindiv">
<!--HTML Form -->
<div class="form_div">
<div class="title">
<h2>Insert Data In Database Using PHP.</h2>
</div>
<form action="insert_backend.php" method="POST" enctype="multipart/form-data">
<!-- Method can be set as POST for hiding values in URL-->
<h2>Form</h2>
<label for="uploadedimage">Small image to upload: </label>
<input type="file" name="uploadedimage" id="uploadedimage"/><br />
<label>Date:</label>
<input class="input" name="date" type="text" value=""><br />
<label>Retrace:</label>
<input class="input" name="retrace" type="text" value=""><br />
<label>Start of Swing Trade:</label>
<input class="input" name="start_of_swing_trade" type="text" value=""><br />
<label>End of Swing Trade:</label>
<input class="input" name="end_of_swing_trade" type="text" value=""><br />
<label>Bull flag:</label>
<input class="input" name="bull_flag" type="text" value=""><br />
<label>Bear flag:</label>
<input class="input" name="bear_flag" type="text" value=""><br />
<label>EMA Crossover:</label>
<input class="input" name="ema_crossover" type="text" value=""><br />
<label>Trading Instrument:</label>
<input class="input" name="trading_instrument" type="text" value=""><br />
<input class="submit" name="submit" type="submit" value="Insert">
</form>
<?php
if (isset($_GET['success']) && $_GET['success']) {
echo "New record created successfully";
} else if (isset($_GET['success']) && !$_GET['success']) {
echo "Failed to insert new record";
}
?>
</div>
</div>
</body>
</html>
Updated my PHP code to include the header location:
$sql = "INSERT into charts (charts_URL, charts_date, charts_retrace, charts_start_of_swing_trade, charts_end_of_swing_trade, charts_bullflag, charts_bearflag, charts_ema_crossover, charts_trading_instrument) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
// s = string, i = integer, d = double, b = blob
//preparing statement
$stmt = $conn->prepare($sql);
if(!$stmt){ exit("prepare failed");}
//binding param
$stmt->bind_param('sssssssss',$target_path, $date, $retrace, $start_of_swing_trade, $end_of_swing_trade, $bull_flag, $bear_flag, $ema_crossover, $trading_instrument);
if(!$stmt){ exit("bind failed");}
//will return 0 if fail
if($stmt->execute() != 0){
$success = true;
}else{
$success = false;
}
header('location:insertchart.php?success='.$success);
exit;
}
}
}
?>
The FINAL code (actually a snippet) that made everything work:
if($stmt->execute() != 0){
$success = true;
header('Location:http://mlsinc.net/chart-submission/insertchart.php?success='.$success);
}else{
$success = false;
header('Location:http://mlsinc.net/chart-submission/insertchart.php?success='.$success);
}
}
//close connection
$conn->close();
Try with -
$stmt->bind_param('sssssssss',$target_path, $date, $retrace, $start_of_swing_trade, $end_of_swing_trade, $bull_flag, $bear_flag, $ema_crossover, $trading_instrument);
if(!$stmt){ exit("bind failed");}
//will return 0 if fail
if($stmt->execute() != 0){
$success = true;
}else{
$success = false;
}
header('location:yourform.php?success='.$success);
exit;
On you form page add a check for it -
if (isset($_GET['success']) && $_GET['success']) {
echo "New record created successfully";
} else if (isset($_GET['success']) && !$_GET['success']) {
echo "Failed to insert new record";
}
To show the message on form page
Store the message in session after inserting the row(since you are redirecting page)
I think the soultion suggested by sgt BOSE will work for you. But instead of passing a "success" GET parameter back to your page containing form, you should use a session variable because the $_GET['success'] will re-print the message if user reloads the window.
Once you print the result stored in session variable make sure to unset it.
Ok I see your problem here, it's actually pretty simple.
the way it works is that the message would be declared inside of the script tag
so you should do something like this so it will call the message.
<html>
<head>
<script type="text/javascript">
//Put the javascript function you want the button to do Here
function show_alert()
{
alert("Form Succesfully Submited");
}
</script>
</head>
<body>
<form action="insert_backend.php" method="POST" enctype="multipart/form-data">
<!-- Method can be set as POST for hiding values in URL-->
<h2>Form</h2>
<label for="uploadedimage">Small image to upload:</label>
<input type="file" name="uploadedimage" id="uploadedimage" />
<br />
<label>Date:</label>
<input class="input" name="date" type="text" value="">
<br />
<label>Retrace:</label>
<input class="input" name="retrace" type="text" value="">
<br />
<label>Start of Swing Trade:</label>
<input class="input" name="start_of_swing_trade" type="text" value="">
<br />
<label>End of Swing Trade:</label>
<input class="input" name="end_of_swing_trade" type="text" value="">
<br />
<label>Bull flag:</label>
<input class="input" name="bull_flag" type="text" value="">
<br />
<label>Bear flag:</label>
<input class="input" name="bear_flag" type="text" value="">
<br />
<label>EMA Crossover:</label>
<input class="input" name="ema_crossover" type="text" value="">
<br />
<label>Trading Instrument:</label>
<input class="input" name="trading_instrument" type="text" value="">
<br />
<!--This is where you tell the script where to load the (ID) for example im using a simple message for you what you need to do is make the id im sure you know how to create a simple (ID) inside of a java ,heck im thirteen im about an expert on it if i can do im sure you can! :) :)
anyway inside the div tag make it look like this: <div id=("PUT ID IN HERE") >
then put you function in the script for wha you want it to do hope this helped you have a nice day!-->
<div>
<input class="button" name="submit" type="submit" onclick="show_alert()" value="Submit">
</div>
</form>
</body>
</html>
Hope that this helps if not dont hate lol.

What is the most efficient way of submitting a form whose inputs are not direct children of the form element itself using native JavaScript?

I am currently creating a form for my employer which tracks individual employee statistics throughout a typical day, such as number of calls, revenue, items sold, etc. I would like to asynchronously update a database using a simple html form without necessarily having to use the entire jQuery library since all I would be using is the $.ajax method, which I do know is effective.
The trouble I'm running into is in finding a way to serialize a form using the form's <input type="submit"> button. My form's input fields are spatially organized using <div></div> tags between the <form> element itself and its <input /> fields themselves, as seen below:
<form name="tour_1" id="tour_1">
<div class="num_calls_cell">
<input type="text" value="3" name="total_calls" autocomplete="off" />
</div>
<div class="acw_cell">
<input type="text" value="24.35" name="acw" autocomplete="off" />
</div>
<div class="rev_cell">
<input type="text" value="125.34" name="revenue" autocomplete="off" />
</div>
<div class="env_cell">
<input type="text" value="0" name="envelopes" autocomplete="off" />
</div>
<div class="pen_cell">
<input type="text" value="1" name="pens" autocomplete="off" />
</div>
<div class="cal_cell">
<input type="text" value="0" name="other" autocomplete="off" />
</div>
<div class="comment_cell">
<input type="text" value="comment" name="comments" autocomplete="off" />
</div>
<div class="submit_cell">
<input type="submit" class="submit_tour" value="Submit Tour" />
</div>
</form>
There are a total of four of these forms that I have in one "day" (you may view the actual project here (http://ryanvold.com/prototype/prototype.php).
How could I most effectively transfer my form data into a PHP file that can easily update a MySQL database using my <input type="submit"> buttons?
You can serialize form like this:
document.getElementById('tour_1').addEventListener('submit', function(e) {
e.preventDefault();
var params = [];
for (var i = 0; i < this.elements.length; i++) {
params.push(this.elements[i].name + '=' + encodeURIComponent(this.elements[i].value));
}
params = params.join('&');
alert(params);
}, false);
This will give you params as follows:
total_calls=3&acw=24.35&revenue=125.34&envelopes=0&pens=1&other=0&comments=comment&=Submit%20Tour
Having constructed params string like this you can use it as ajax request POST parameters:
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(params);
This is just an example, remember to take care of IE if you need to support it (attachEvent).
Demo: http://jsfiddle.net/LnLaT/

Categories