We have a booking form that POSTs to the parent company website. Because this is a different domain we need to implement the GA _linkByPost to pass the GA tracking cookie info across domains.
As the booking form is in a .NET user control it does a postback. On postback we validate, wrap up the booking info, and write a form back to the client with hidden elements required by the target booking engine and add line of javascript to submit the form.
Below is the javascript function I'm using to submit the form:
function postBookingForm() {
var thisForm = document.getElementById('PostForm');
_gaq.push(['_linkByPost', thisForm]);
thisForm.submit();
}
And the relevant form info:
<form id="PostForm" name="PostForm" action="ClientBookingEngineUrl" method="post" >
booking form info in here
</form>
The result is that we fill in the form, hit submit which does a round trip to the server generates a new form and POSTs the info. This all works fine apart from the URL loses the GA cookie info from the query string. If I comment out the form submit line and look at source code I can see the GA cookie info on the querystring - but when posting, I do not see the querystring (using Fiddler).
To clarify:
The above technique works and does what we want with regards to POSTing form data to the booking engine and taking the user there.
If the submit line is commented out you can see the form with the modified action that has the GA stuff appended (using Firebug).
If the form is submitted with the submit line, the querystring info is removed (confirmed by Fiddler).
Am I missing something obvious? Are there some gotchas regarding JS submit, form POSTs and querystrings? Or is there a simple trick I'm missing?
Cheers
EDIT 1
An oddity has occured.
If I alert the form action before and after the _gaqPush then we can see the URL in its before and after state and it's as expected.
alert('1 form action = ' + thisForm.action);
_gaq.push(['_linkByPost', thisForm]);
alert('2 form action = ' + thisForm.action);
Alert 1 shows the pre-modified action and alert 2 shows the action with the GA info.
With the alerts in place it submits WITH the GA info in the query string.
If I comment out the alerts the GA info is NOT in the query string...
I'm starting to think the form or something is not ready so I'm trying it with JQuery's document ready.
EDIT 2
Wrapping the method call in document ready doesn't help. I'm confused as to why action URL is correct AFTER displaying it in an alert but incorrect if I don't alert it.
Answering this for posterity.
The problem is the _qaq (Google Analytics Queue) hasn't had time to modify the form before the call to submit() the form.
The solution is to push a function onto the _gaq object that submits the form so it will happen directly after the form modification is done.
function postBookingForm() {
var thisForm = document.getElementById('PostForm');
_gaq.push(['_linkByPost', thisForm]);
_gaq.push(function() { thisForm.submit(); });
}
I tried a simple HTML page that calls _gaqPush and submits immediately. This also fails.
Adding a 1000ms delay works (for the most part) so I suspect the alerts just gave the GA script time to modify the form.
I'm closing/accepting this as it seems down to submitting the form too quickly after the GA call.
Related
I have a php form that works perfectly. However, when the form submits, I want to display a modal and take the user back to the homepage. I have looked this past two hours online but have found no conclusive evidence. My current code is;
if($sentMail) //output success or failure messages
{
?><script>
$(function() {
$("#thankyouModal").modal();
});
</script>
<?php
}else{
die('Could not send mail!');
}
The form collects data then sends all data as an email. I have tried using only php, jquery, amongst everything else. I simply want a modal that says a brief thank you, your form has submitted whilst re-directing the user to the index.html page. Does anyone have any ideas?
Regards,
Michael
If you want to show the message while the form is posting (whether or not it will succeed), use jquery to swallow the onSubmit() event.
$('form').on('submit', function(e){
e.preventDefault();
$("#thankyouModal").modal();
$('form').submit();
});
If you care about if the email is successful, pass a variable back to the view and conditionally show the modal, but this will be serverside validation (will only know after form submission and re-rendering of the view). Otherwise look into doing an asynchronous post with $.ajax
UPDATE 2
Looks like I am having trouble accessing document elements (including form) from within the callback (onSubmit function) registered with invisible reCAPTCHA. Updated code below.
In browser console, I get the error message below when JS reaches "document.getElementById("info_form").submit()" call in JS:
10:26:47.556 TypeError: document.getElementById(...).submit is not a function 1 selector.php:13:9
The image CAPTCHA when it comes up is solved correctly and alert dialog displays it correctly. But, I can't submit form explicitly within callback to my backend. Please note that as per Google instructions in link below in message, I need to call preventDefault() as specified below. If I delete it, the reCAPTCHA flow is interrupted.
UPDATE
So, it looks like the "event.preventDefault();" is the key line here. If I have it, the reCAPTCHA (i.e. the image selection grid) gets displayed and I can interact with the widget. However, the POST parameters don't get sent. If I comment out the preventDefault(), the POST goes through correctly - BUT the reCAPTCHA flow does not start. This means, that while the other POST params get sent, the important reCAPTCHA data does not get sent since that flow is not executed at all.
So, how do I go about this? Looks like I need to call "preventDefault" before "grecaptcha.execute()" to enable reCAPTCHA flow (as Google also shows in their snippet). But doing so, messes up the POST data somehow. I am also explicitly calling "document.getElementById("info_form").submit()", but not helping. Any ideas would be great. Thx!
Also, Google's invisible reCAPTCHA is a relatively new construct and still in beta. Could be some core issues re: that. What we are all regularly used to is their regular reCAPTCHA where we see the "I am not a robot" checkbox. Invisible reCAPTCHA does not have that first line UI widget - and only steps you up to image CAPTCHA if nedeeded.
ORIGINAL POST
I need your help in figuring out why my 1) button onclick = validate function and 2) my form POST cannot co-exist.
Specifically, if I comment out the "document.getElementById('submit').onclick = validate" below, my form POST goes through successfully. However, if I register the validate function, the form POST does not work. Google tells me (Google link provided below) that if I want to validate input before performing invisible reCAPTCHA, I need to call "grecaptcha.execute();" during button onclick event.
So, my general question is, after executing (or within) the button onclick = validate function, how I can make sure that the info_form is submitted normally via POST so I can see it in my backend PHP? Not necessarily that the POST "itself" isn't working - but the parameters that would get submitted via POST may be getting messed up somehow - just a thought.
Source code and further code specific comments below. Also, please note that I already have the other two forms of reCAPTCHA binding working in the Google link. The "grecaptcha.execute()" variant is the only one I am having trouble with.
<?php
include 'msg_recaptcha.php'; // use the debugMessage output
?>
<html>
<head>
<script>
function onSubmit(callbackInput)
{
var message = "g-recaptcha-response token successfully received.\n";
message += "Token = ";
message += callbackInput;
alert(message);
document.getElementById("info_form").submit();
}
function validate(event) {
event.preventDefault();
if (!document.getElementById('firstname').value) {
alert("Please enter name");
} else {
grecaptcha.execute();
}
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form id='info_form' action="invisible_recaptcha_form.php" method="post">
First name: <input id="firstname" name="firstname">
Second name: <input id="secondname" name="secondname">
<div id='recaptcha' class="g-recaptcha"
data-sitekey="<Site key (public) from Google>"
data-callback="onSubmit"
data-size="invisible">
</div>
<button id='submit'>submit</button>
If I comment out the "onclick = validate" line below, my server PHP will receive the form details via POST - including first name. However, I can't comment it out in final solution, since I need to run the recaptcha "execute" function in validate() function as per Google's instructions https://developers.google.com/recaptcha/docs/invisible. The problem with Google's instructions is that, they don't show how to do the POST along with their grecaptcha.execute() requirements - and I would need both to ensure the payload from the reCAPTCHA operation gets sent in the POST to my backend, so that my backend can talk to Google server's to validate the reCAPTCHA payload.
<script>
document.getElementById('submit').onclick = validate;
</script>
<div id="debugmessage"><?=$debugMessage?> </div>
Thanks everyone!
You have to change your onSubmit JS function to execute form submit after recaptcha validation.
function onSubmit(token) {
alert('thanks ' + document.getElementById('firstname').value);
document.getElementById("info_form").submit();
}
UPDATE
When you call event.preventDefault() at your onsubmit eventHandler, you say to the browser to not execute form submit by default and that YOU will do it when you need.
I can see you are accepting parameter into validate function
function validate(event) {
event.preventDefault();
if (!document.getElementById('firstname').value) {
alert("Please enter name");
} else {
grecaptcha.execute();
}
but you are not passing any parameter to validate
document.getElementById('submit').onclick = validate
that is the reason its giving you error.
modify your validate function to take no argument. I'm thinking why you need to take argument into validate function when you are not using it anywhere?
I am having issue with XHR call made to GitHub domain from localhost.
Upon clicking on the button Click to get User Profile with Ajax+JS, a JS function getUser() gets called. Code works as expected, i.e., gets a particular GitHub user details(full name and avatar) and displays on the page.
## Code for "Click to get User Profile with Ajax+JS" button
<input type="button" value="Click to get User Profile with Ajax+JS" onclick="getUser()" id="jsBtn" />
BUT, when I call the same JS function on form submission using submit button (or return), it does not return the expected result i.e., user details.
## Code for "Submit" button
<form id="myForm" onsubmit="getUser()">
#...
<input type="submit"/>
</form>
Upon inspecting under Network, I see the difference in the way Request URL is formed in Request Headers Section:
## With GitHub username input as kirtithorat
## First Case With "Click to get User Profile with Ajax+JS" button
Request URL:https://api.github.com/users/kirtithorat
## Second Case With "submit" button
Request URL:http://localhost:3000/html_file_name?username=kirtithorat
Why the difference in behavior? The same JS function works for onclick but not for onsubmit.
NOTE:
I am looking for a Pure JS Solution. I know how to do it in
jQuery.
I don't actually want the form to be submitted, only the
onSubmit event should be triggered.
Here is my JSFiddle
Your second URL looks like the form submission, NOT the result of calling getUser() (the getUser() ajax call probably came right before the form submission).
If you don't want the form to actually submit (which it appears is how you want it) and only want your onSubmit handler to be called, then you need to make sure the default behavior of submitting the form is prevented.
You can block form submission by just adding a
return false;
to the end of your getUser() onsubmit handler function.
Or, you can block the form submission by passing the event into the getUser() function and using e.preventDefault().
The other reason to block the form submission is that the page will reload with the results of the form submission and your javascript will not still be active to receive the results of the getUser() ajax call. So, you must use one and only one of the Ajax call or the form submission (it looks like you just want the ajax call so you can prevent the form submission).
I'm new to web design, and I have a question about cache.
I have a page called buy-form.php that gets form data from form.php. I want it to have the cache error that makes Google Chrome read "Confirm Form Submission" when the is page accessed manually.
For example, I only want the page to be accessible when form data is submitted. If someone were to type in the page on the address bar, it should have an error.
A javascript alert("Confirm Form Submission"); can handle your request, and be effective across browsers. Call a function for the event <input [other attributes here] onclick=myFunction()> that has the alert you want. The alert will stop execution of the page until it is confirmed (selected). Attach a security code to your form submission and PHP can check for it and die; if it is not valid.
Add this statement to your buy-form.php:
if(empty($_POST))
{
echo "<script type='text/javascript'>alert('Error!');</script>";
}
You can replace 'Error!' to whatever you prefer
I'm using a HTML form to allow a user to upload some files to a java servlet and start some analysis. When the user clicks submit I use a javascript function to do some quick validation on the form i.e. have they selected the right options, entered a valid email etc.
The form data is then passed to the doPost() method in my servlet where I do some more complex checking for errors in the input data. After this the user is either forwarded to an error page or notified that the job has been started.
What I would like to do is display a progress page while the error checking is taking place in the servlet. It seems I can't forward the user to the progress page in the servlet as this commits the response and I can't carry on the checking and then later forward the user to the relevant page. This is explained here.
I think the answer might be to display the progress page when the user clicks the submit button and before the form data is sent to the servlet. This could be done in the javascript validation in the form. So far my attempts at this have failed. I think I'm misunderstanding something!
I've tried the advice listed here to use window.location.replace(...) but it doesn't seem to work. I've also tried using a button instead of a submit input type and defining the form action in the javascript as shown here.
My javascript validation function is
<script language="JavaScript">
<!-- // ignore if non JS browser
function Validator(form) {
var error = "";
if (form.family.value == "") {
error += "Please upload a family file\n";
}
if (error != "") {
alert(error);
return (false);
} else {
window.location.replace("http://stackoverflow.com");
return (true);
}
}
and my form is submitted using <form method="POST" enctype="multipart/form-data" action="runDupliPHY.do" onsubmit="return Validator(this);"> from a submit input.
Any examples of how to show a progress page before submitting the form so the user sees the progress page while the servlet processes the form data would be great.