We have clients that we want to collect some of their form submission data for. A user will fill out a form on their site and when the form is submitted, the following javascript is called:
/* 4. Below script will get all field name/value pairs for given form */
function cpcshowElements(f) {
var formElements = "";
for (var n=0; n < f.elements.length; n++) {
box = f.elements[n];
if (!f.elements[n].value == ""){
formElements += box.name + ":" + f.elements[n].value + ",\n";
}
}
var track = new Image();
/*send data to us*/
track.src="https://www.xxx.com/form_record.cfm?form="+formElements;
//alert("The elements in the form '" + f.name + "' are:\n\n" + formElements);
}
This calls code on our end that should grab the data sent and save it. This works great, but doesn't work all of the time. When testing, we seem to not get the data consistently. I haven't been able to figure out why this works sometimes and not others. I'm not a javascript expert so I'm not sure if it's just the way javascript works. The only thing I've been able to think might be the issue is that once the clients website finishes processing the form on their end and the user is directed to another page, the script will stop running if it hasn't already finished and so we won't get the data. Anyone have any ideas? Am I on the right track here? Any ideas on how to make it so we will get the data every time?
You could you jQuery Framework with serialize function tosubmit the form and get it input's values.
$("#bottonId").click(function(){
imageObj.src ="http://www.mypage.com/mypage?" +$("#form's ID").serialize();
});
Related
I'm currently using geolocation to get the clients browser location. Right now, I store the values in local storage and then send them when the user submits the form. I would like to send them before the page even loads however, so that I can run the required calculations when the page is first opened on the client side.
Here is the javascript I am using to get the location (which works well). It runs before the page is loaded.
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
function foundLocation(position) {
if (isPostBack == true) {
return;
}
var lat = position.coords.latitude;
var long = position.coords.longitude;
this.localStorage.setItem("lat", Math.round(lat * 1000000) / 1000000);
this.localStorage.setItem("long", Math.round(long * 1000000) / 1000000);
}
I then use window.onload and call the values in storage to load them on the form automatically. The user then clicks a button and the form submits with the values.
How can I just send those values directly to the server? This would allow me to run the required location calculations without the user even having to click. I know I could just automate the submit button click after after the window.onload fires, but I don't want it to look like the form loads, submits then posts back if that makes sense.
I'm new to asp.net so I'm not even sure what question to ask here so my apologies if this is something simple I'm just looking over.
EDIT: The "possible duplicate" is regarding executing js before page load which I am already doing. My question is more on how to send the values back to the server before loads complete.
You can create an empty page as a first step. Then that page can perform that calculation and redirect to the final page sending that info through a POST or a GET.
window.location.href = "your-final-page.aspx?lat=" + lat + "&long=" + long;
I'm a total novice so please excuse my ignorance.
I have website with a php shopping cart that refreshes to the cart page when something is added to to the cart. I want to modify it so that when a product is added, the cart updates in the background and the product page does not refresh but updates the html in various divs with unique id's.
I have managed to achieve this but I am sure that there must be a simpler way as my solution involves a loop that trawls through all the forms on the product page rather than just updating the divs from the form that was submitted.
Here's my JavaScript which is inside the <head> tags of the product page:
<script>
$(document).ready(function(){
$("[id^=ectform]").ajaxForm({ // any form id beginning with ectform
success:function(){
$.ajaxSetup({ cache: false });
$("#div1").load("jsrefresh.php"); // update html in div in minicart
for (i = 0; i < count; i++) { // count holds the number of forms on the page
var d = "#glc" + i; // div id to update
var f ="#gld" + i; // another div id to update
var e = eval("z" + i); // product id
$(f).html('loading...').load("jsrefreshincart.php",{ prodynum: e, divno: d});
};
}
});
});
</script>
The script utilises ajaxForm to wait for the successful submission of any form with an Id beginning with ectform. On success, The form is submitted to the cart script which updates the cart contents and then ajax .load is used to call jsrefresh.php which echoes back the updated html to a div in a mini cart which is displayed at the top of the screen. Then (this is the bit that needs doing properly) jsrefreshincart.php is called in a loop ( the variable count holds the total number of forms on the page ) which updates html in all divs within all the forms on the page with information about how many items are in the cart and how much they cost.
Is there any way of doing this without the loop as only the divs within the form that was submitted need to be updated ?
The major problem here is not that you have a loop, but that you have a server-call inside of it. The best way to handle this is to change the way that jsrefreshincart.php handles calls from the server. Instead of having multiple calls inside the loop, collect all the data and have a single call outside the loop.
I don't think that's something the jQuery Form plugin can handle; rather, you'll probably have to write some custom code (like below):
<script>
$(document).ready(function() {
$("[id^=ectform]").on('submit', function(e) {
e.preventDefault();
$('[id^=gld]').html('loading...'); // Trigger all loading messages simultaneously
var formNums = [];
for (i = 0; i < count; i++) {
formNums.push(i);
}
$.post({
$(this).attr('action'), // Where to send the form action
formNums: formNums, // The data to send when submitting the Ajax call
refreshCartData // The callback used to refresh the page
});
});
});
// Called automatically when the server responds with data
function refreshCartData(data) {
// Loop through all forms and update them
for (var i = 0; i < data.length; i++) {
// Update HTML
$('#gld' + data[i].formNum).html(data[i].cartHTML);
}
}
</script>
Your jsrefreshincart.php should return data for all of this. For example:
<?php
// Used to load the cart data - I'm sure you have something similar
require_once('cart.php');
// Send everything back as JSON
header('Content-type: application/json');
// Initialize the data to send back
$data = array();
// Iterate over all data send to the server
foreach ($_POST['formNums'] as $formNum) {
$data[] = array(
// The unique ID for the form number
'formNum' => $formNum,
// Again, however you get the view data for your cart line items works fine
'cartHTML' => Cart::getCartHTML($formNum)
);
}
// Spit out the JSON data
echo json_encode($data);
Some additional suggestions:
Your variables d, e, and f in your original code are not necessarily all updated during the Ajax round-trip
You need to add more commenting and indentation - it seems simple, but proper documentation is the best way to communicate your problems to other developers
Consider using a different way to keep track of data besides a "count of forms" - classes can work too
My assumption is that anything starting with an ID of ectform is a form to have this functionality captured in; if this is not the case, parts of the above solution might not make sense
After looking at the suggestion by Dykotomee (thank you), it gave me the idea how I could amend my script to work without the loop:
<script>
$(document).ready(function(){ // when DOM is ready
$("[id^=ectform]").on('submit', function(e) { // on submission of any form with id beginning "ectform"
e.preventDefault(); // prevent the form itself submitting the data
var subformid = $(this).attr('id'); // set variable with the id of the submitted form
$(this).ajaxSubmit({ // submit the form via ajax which will add the product to the cart
success:function(){ //on successful submission of the form
$.ajaxSetup({ cache: false }); // turn off cache so the updates will refresh on all browsers
$("#div1").load("jsrefresh.php"); // load div in mini cart with new updated cart quantity
var str = subformid.replace("ectform", ""); // trim subformid to leave just the end digits and call this variable str
var d = "#glc" + str; // not important for purposes of explanation
var f ="#gld" + str; // f is the id of the div in the submitted form to be updated
var e = eval("z" + str); // e is the product number
$(f).html('Adding item to Cart...').load("jsrefreshincart.php",{ prodynum: e, divno: d}); // send data to jsrereshincart.php and load updated html into div f.
}
});
});
});
</script>
I used ajaxSubmit instead of ajaxForm which allowed me to trigger the submission of the form using $("[id^=ectform]").on('submit', function(e) {.......
I was then able to catch the id of the form submitted with var subformid = $(this).attr('id');
Now I had the id of the submitted form , I was able to use ajax .load to get the updated cart HTML into the div in that particular form rather than looping through all the forms and updating them one by one.
The script now only makes a total of 2 server calls per form submission. My previous script made up to 50 calls when a maximum of 25 products/forms were displayed on the products page.
I could modify this script and the php scripts to do everything with a single call but other pages on the site don't have products, just the mini cart so it's easier to keep the scripts separate.
I have a page with an select box, which fires an onChange event. In this Java-Script snippet, I would like to reload the current page, including the GET and POST parameters that where sent during request. AFAIK, this can be achieved by using window.location.reload(), or window.location.href = window.location.href when sending POST data is not required.
However, I need to append an additional value (actually, the value of the select element), additionally to the previously sent element. I do not care whether the data is sent using POST or GET. Is there a way to achieve the desired behavior?
To accomplish this you are going to have to rebuild a request from scratch. In the case of get requests, the arguments are easily accessible in the query string but post requests are a little trickier. You will need to stash all that data in hidden input elements or something so that you can access it.
Then you can try something like this:
var queryString = windlow.location.search; //args from a previous get
var postArgs = $("#myPostArgsForm").serialize(); //args from a previous post... these need to be saved and added to the html by the server
//your additional data... this part you probably need to adapt
//to fit your specific needs. this is an example
var myNewArgName = encodeURIComponent("newArg");
var myNewArgVal = encodeURIComponent("Hello!");
var myNewArgString = myNewArgName + "=" + myNewArgVal;
//if there is no queryString, begin with ?
if(!queryString) {
queryString = "?"
}
//if there is, then we need an & before the next args
else {
myNewArgString = "&" + myNewArgString;
}
//add your new data
queryString += myNewArgString;
//add anything from a previous post
if(postArgs) {
queryString += "&" + postArgs;
}
window.location.href = window.location.hostname + window.location.pathname + querystring
<form id="myPostArgsForm">
<input type="hidden" name="prevQuery" value="whats up?" />
</form>
Pretty simple really; have onChange fire a function that uses getElementById to figure out the selector value and then just use window.location to send the browser to the literal: http://yourdomain.com/yourpage.html?selectval=123
then, in the body onload() method, fire another JS function that checks the "get var" like:
function (GetSelector) {
var TheSelectorWas = getUrlVars()["selectval"];
alert(TheSelectorWas);
}
and do whatever you need to do in that function (document.writes, etc). BTW, posting the actual code you're using is always a good idea.
-Arne
We have a number of clients that have agreed to send us their form data once a form is submitted on their site. Is this possible and what is the best way to handle this? Our site is built in coldfusion while the client site varies.
I had the client add a script tag to include a javascript file from our server on their form page. Also had them add an onClick event to their form button so this javascript is called on submission of their form.
This is the javascript file:
function cpcshowElements(f) {
var formElements = "";
for (var n=0; n < f.elements.length; n++) {
box = f.elements[n];
formElements += box.name + ":" + f.elements[n].value + ",\n";
}
var track = new Image();
/*send data to us*/
track.src="http://XXX.net/form_record.cfm?form="+ formElements + "&self=" + this.location;
}
On form submission the cpcshowElements function is called, formats the form data, appends it to the end of the XXX.net/...and calls that url. The form_record.cfm page basically does some checks and inserts the data into a table.
This process does work, however not consistently. The data doesn't always make it into the database. That is the problem. Is there another way to do this that won't have data loss?
The data getting to the database is pretty deep down the chain. The first step is to figure out where the request isn't coming through. Find the weak link, and then fix that part.
Chances are, there are other issues causing the failure than this piece of javascript. Test each part of the process and figure out where the problem lies. Chances are, it isn't in the javascript.
Check whether the form on the serve is being submitted by method other than onClick. If the form can be submitted by hitting enter or tabbing and hitting enter or the spacebar, than you are missing some submits. Would work more consistently with onSubmit rather than onClick.
Example:
<form onsubmit="your_function_here">
Also, if the form is submitting and then moving on to another page, you javascript code may not have enough time to fire. In that case, put a delay into your function to allow the GET request for the image to be made before the page evaporates.
I want to go back to previous JSP page with all its value retained on click of previous button in present JSP page. I am using history.back() in JS, but not able to retain the previous field value. How to retain the field values of the previous page?
I would suggest using JQuery and a server side session variable to store the values.
make sure you have an html id on each form element you need to keep
on unload, loop though the elements and send them over to the server to be saved
$(window).unload(function() {
var formValues = {}
//get the form elements
elements.each(function() {
var fieldID = $(this).attr("id");
formValues[fieldID] = $(this).val();
}
json_form = JSON.stringify(formValues);
$.post("/save_form_values/", {form : json_form} );
I haven't included any code for storing on the server (I found it pretty straightforward with django / python).
make another ajax call when you reload the page
$(document).ready(function() {
$.get("/get_form_values/", function(data) {
var formValues = JSON.parse(data);
$.each(formValues, function(fieldID, value) {
id_selector = '#' + fieldID;
$(id_selector).val(value);
}
}
}