I've got a bit of a weird problem.
I'm creating a location based web app that is using a javascript function to get a user's GPS coordinates. I have a form with a submit button, and when that submit button is clicked, the function is called (onclick='getCoords()"). The javascript then sets that values of two hidden fields (latitude and longitude) to the GPS coords.
My issue is this: PHP is 'beating' the javascript in the sense that the field values aren't being set in time, so that each value becomes a 0. I've done a bunch of testing, and this is definitely the issue. If I do something like set a seperate button to run the javascript function, the run the form everything works fine.
Any ideas on how to solve this problem?
Gists:
https://gist.github.com/2425419
https://gist.github.com/2425394
https://gist.github.com/2425391
Along the lines of what Volkner said, block submit using a submit handler (call preventDefault), then submit at the end of itsWorking. You can either call .submit() to do the submission, or use AJAX.
I think the crux of your problem is that an <input type="image"> will submit a form just as sure as <input type="submit"> will.
However, to fix this as is, add event as a parameter to both the call and declaration of getUserLocation(event).
Then edit your JavaScript as follows:
function getUserLocation(event) {
event.preventDefault(); // prevents form from submitting
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(itsWorking, notWorking);
}
else {
alert("Dang! Your browser doesn't support finding your location, use the zipcode method below.");
}
};
function itsWorking(position) {
var lat = position.coords.latitude;
var longi = position.coords.longitude;
var finalLat = Math.round(lat*1000000)/1000000
var finalLong = Math.round(longi*1000000)/1000000
$("#longi").val(finalLong);
$("#lati").val(finalLat);
document.getElementById('findoneform').submit(); // submits form since we were successful
};
But like I originally stated, it seems if you used an img tag instead of <input type="image">, that would prevent the form from sending in the first place (and maybe you did this on purpose, because you wanted to have two ways to submit the form?).
This issue happens because the page unloads (submits the form) before the geolocator's done doing its thing, but this way, we stop the form from submitting, and itsWorking() only gets called AFTER the geolocator has done its thing, so we don't submit the form until the end of itsWorking() when we've done everything we wanted to do.
Related
I've Googled and searched on SO quite a bit for this unique problem, but not really finding my exact solution.
I have a basic form with X number of inputs. At some point in the form, the user as the freedom to add inputs via button click if needed. When they submit the form, it goes to another page to collect the posted form data, but I want the ability for the user to click "Back" (or send them back programmatically) if the submit fails.
I have error checking setup prior to submit via javascript, but there are other things (such as a PHP mailer) that could fail and I want them to be able to resubmit their data.
The issue of course is when the browser clicks back, it - at best - refreshes the initial form that was in the DOM with input data, but I lose all of the dynamically added inputs.
I want to capture the form/data in a session and have it repopulate the DOM with the submitted version created by the user on click back.
The closest I've come is doing something like this on SUBMIT:
var theForm = $('#myForm');
sessionStorage.setItem('formData', JSON.stringify(theForm.clone(true).html().toString());
And this on postback/click back:
$('#myForm').replaceWith(JSON.parse(sessionStorage.getItem("formData")));
The problem here is I get my form, but not the data! Do I need to iterate over each input to get my data put back in the recreated form?? Why doesn't it grab the data when .clone(true)ed?
Here's the answer I ultimately got to work.
Upon form validation, I set the session to hold the form data like so:
var theForm = $('#MyForm');
sessionStorage.setItem('formHTML', JSON.stringify(theForm.clone(true).html()));
theForm.find('input,select,textarea').each(function(){
sessionStorage.setItem(this.name,this.value);
});
Then, when the DOM loads again, I have this that checks for the session and populates the form with data if it exists:
$(document).ready(function(){
if (sessionStorage.getItem("formHTML")) {
$('#MyForm').html($.parseJSON(sessionStorage.getItem("formHTML")));
}
$('#MyForm').find('input,select,textarea').each(function(i,elem){
var sessItem = elem.name, sessValue = '';
if (sessValue = sessionStorage.getItem(sessItem)) {
if(elem.type=='radio' && elem.value==sessValue){
alert(elem[i].type+' has value of "'+elem[i].value+'"');
$('[name='+sessItem+']')[i].prop('checked',true);
}
else if(elem.type=='textarea'){
alert(elem.type);
$('[name='+sessItem+']').val(sessValue);
}
else
{
$('[name='+sessItem+']').val(sessValue);
}
}
});
});
I'm pretty sure I'm missing something simple here, but it's driving me nuts !
This isn't the first form I'm using in PHP, but the first time submitting a hidden value.
When a menu item is clicked, I want to submit the page to itself - setting a simple parameter, so the php code does the processing.
The page gets submitted fine, but the hidden variable I set isn't available through _GET, _POST or _REQUEST. It should be _GET since that is what I've set as the method.
Here is the code if anyone can spot where I'm going wrong..
paramCustom is the one that I'm trying to set and work on.
The menu is a series of DIVs & anchors :
Option Xyz
The activateMenu javascript function is :
function activateMenu(optionTaken)
{
// Set the hidden variable
document.getElementById('paramCustom').value = optionTaken;
// Display it to confirm it is set correctly
var tt = document.getElementById('paramCustom').value;
console.log("paramCustom set to : " + tt);
// Submit the form
document.getElementById('linkSubmit').submit();
return false;
}
The form is coded this way :
<form method="get" action="showProducts.php" id="linkSubmit">
<input type="hidden" id="paramCustom" name="paramCustom" />
<input type="submit" tabindex="-1" style="display:none;" />
</form>
In the php of the same page I'm trying to spit them out but all of them show blank !!
echo "paramCustom get is : ".$_GET['paramCustom']."<br/>"; // This should work
echo "paramCustom request is : ".$_REQUEST['paramCustom']."<br/>";
echo "paramCustom post is : ".$_POST['paramCustom']."<br/>";
OK, problem is that you are not actually stopping the event from firing. So clicking on the link, the function gets called, form submitted but you are not actually stopping the event in the onclick. So form submits but is immediately redirected to the href of the link cancelling the form submit. When the href is blank, it defaults back to the page you are currently on.
The way you are adding the onclick to the link (using an inline attribute) is like wrapping the event in a closure. So when onclick fires, what is really fired is more like function(){ activateMenu('option-xyz'); }. Your call to activateMenu is returning false, but the closure around it is not. You can just add return in front of activateMenu to have the event itself return false and cancel. Change the link like so:
Option Xyz
And then the actual event itself will return false, not just the function.
Here is a simple example to illustrate what is happening.
Doing a little change to the HTML you can set the inline event via Javascript, which is a way better:
<a id="xyz" href="#">Option Xyz</a>
And this is the Javascript edited for your purpose:
function activateMenu(optionTaken)
{
var paramCustom = document.getElementById('paramCustom');
// Set the hidden variable
paramCustom.value = optionTaken;
// Display it to confirm it is set correctly
var tt = paramCustom.value;
console.log("paramCustom set to : " + tt);
// Submit the form
document.getElementById('linkSubmit').submit();
return false;
}
window.onload = (function() {
document.getElementById('xyz').onclick = function() {
activateMenu('option-xyz');
};
});
In PHP, as you know, $_GET gets the parameters of query string, $_POST of the POST data and $_REQUEST is a concat of the two arrays. In this case your method is GET so the value can be retrieved via _GET and _REQUEST, _POST is not going to work. Your code didn't worked to me probably because you had your function defined before DOM was loaded, so the event, when fired, probably throwed an exception.
This doesn't work because you haven't assigned a value. PHP won't recognize a field with a null value.
<input type="hidden" id="paramCustom" name="paramCustom" value="somevaluehere" />
[edit]
After testing this myself, it's because the onclick event is not behaving the way you anticipate. The easiest way to fix this is to use a HREF for you link. It's actually bad practice to rely solely on the onclick event anyway.
Option Xyz
This works perfectly.
The proper way to write an onclick looks like this:
Option Xyz
This works as well.
I've been using JQuery lately and it might be worth a shot.
Download the latest JQuery script and just link it to your page.
function activateMenu(optionTaken)
{
// Set the hidden variable
$("#paramCustom").val() = optionTaken;
// Display it to confirm it is set correctly
var tt = $("#paramCustom").val();
console.log("paramCustom set to : " + tt);
// Submit the form
document.getElementById('linkSubmit').submit();
return false;
}
This isn't that much different than what you had but maybe JQuery will do a better job of assigning the value to your hidden field...
Cheers,
K
I have a simple form which accepts a Title and a Contents variable from a textbox and a textarea. The form will send its data to a file called add-post.php. However, I am looking for a way to alert the user that either the textbox or the textarea has invalid data (is empty) in case they click the submission button.
I was thinking that an alert() popup box would be the best idea because it doesn't redirect to any other page and the user never loses their data (imagine they entered a whole lot of text but forgot a title. Sending the data to add-post.php and performing the check there will result in loss of data for the user).
However, I'm not sure how to actually implement the alert() popup. How would I make it so that the check is done AFTER they have clicked the submit button but BEFORE the data is sent off to the next file. Any advice is appreciated.
On your form add something like this
<form name="frm1" onsubmit="InputChecker()">
Then in javascript
<script type="text/javascript">
function InputChecker()
{
if(document.getElementById({formElement}) != '') { // not empty
alert("This element needs data"); // Pop an alert
return false; // Prevent form from submitting
}
}
</script>
Also as others have said jQuery makes this a little bit easier. I highly recommend the jQuery Validate Plugin
Some people do find the alert box "annoying", so it may be better to append a message into the DOM to let the user know what needs to be fixed. This is useful if there are numerous errors as the errors will be more persistent allowing the user to see all the things they need to be fixed. Again, the jQuery Validate plugin has this functionality built in.
Attach an onsubmit event to the form, and return false; to stop the submission if checks fail.
Form validation with Javascript. Or easier with jQuery.
Basically, validate the form when the submit button is clicked (with an onsubmit handler), and then use an alert() box if needed. By the way, people usually hate alert boxes.
You have a number of options when it comes to client side validation. This is just one.
<form id="tehForm" method="post">
<input type="text" id="data2check" >
<input type="button" id="btnSubmit" />
</form>
<script type="text/javascript">
function submit_form(){
if(document.getElementById("data2check").value!="correct value"){
alert("this is wrong");
}else{
document.getElementById("tehForm").submit();
}
}
</script>
For a more indepth example check out this link
Hello all I'm new to this whole thing still.
I would like some help figuring out how to do this please. I can pull info out of a database and put stuff in using ajax/javascript but I cant figure out how to complete the problem below. I want to be able to make my php form submit and update with out page refresh.
Example.
Page1. Main page
-Drop down
javascript/Ajax on change of dropdown get info from page 2.
Form from page two now displays without page refresh on change of drop down.
When submit button from page two is pressed inserts form data into Mysql database.
Once new data is submitted into sql data base the form updates and shows data in mysql database for the specific ID in the drop down.
Page2.
form drop down info.
Form is filled with info if there is data in the database for it.
Javascript/Ajax on button submit sends input fields to page 3
Page 3.
insert data into mysql using javascript/ajax so no page refresh is required
Thanks
You need to loop through all the input fields in your form, package them into a query string, and send that to your form processing page.
Something like
var queryString = '';
for(var i = 0; i < document.formName.elements.length; ++i) {
queryString += document.formName.elements[i].name + '=';
queryString += document.formName.elements[i].value + '&';
}
//trim off the last '&' here
If you're using select boxes, you'll have to identify them in the loop above and extract their value a little differently. The query string format I used here is for a POST query; in a GET query, you need to append this to the url of the form processing page with a '?'
Consider the following example using jQuery (though you could adapt this to raw js or a different js library):
function doSubmit(event) {
event.preventDefault();
var $this = $(this);
$.ajax({
url: $this.attr('action'),
type: 'post',
data: $this.serilaize(),
success(responseHtml) {
// assume responseHtml is the next form
var newForm = ajaxifiyForm($('form', responseHtml));
$this.unbind('submit').replaceWith(newForm);
}
});
return false;
}
function ajaxifyForm(form) {
return $(form).submit(doSubmit);
}
$(document).ready(function(){
ajaxifyForm($('#your-form'));
});
Here we rely on the first page load to have the form already included on the server side. When the DOM is ready we attach an event handler to the submit event of the form. This handler overrides the normal submission process and instead uses ajax. It submits to the URL we specified in the action attribute.
When a post is successful it takes the HTML response from that post and replaces the original form with it after applying the same handler we used on the original form. This relies on the assumption that the php script(s) we are posting to always return the next form with all its values filled out.
Keep in mind you can submit file data in this way. Youd need to use an iframe as an intermediary to do that (there are other ways to do this as well that doesnt use an iframe). you can google ajax file upload for solutions to that problem.
I think I got a classic problem but I was not able to find a working solution so far.
I have got a form , the user clicks "Send" and everything works fine using a PRG pattern and doing both client-side and server-side validation.
The problem arises when any user (let's assume he entered valid inputs) clicks more then once quickly before the server script ends its execution...
I do not get any duplicated entry because I took care of that but the browser does not go to my "thanks for submitting page".
Instead it re-submits the same page with the same values and what I get are the custom errors I set to warn the user he is trying to enter details already stored in the database. The details sent in the first place are all in the database but the user has no chance to know that.
I tried to disable the submit button on a submit event using jQuery but in that case the data are not submitted.
HTML
<div id="send-button-container">
<input id="send-emails" type="submit" name="send_emails" value="Send"/>
</div>
jQuery
$(document).ready(function(){
$('#mail-form').submit(function(){
$('#send-emails').attr('disabled','disabled');
});
});
I am wondering if I can force a submission using Javascript after disabling the button and also how to deal with UAs with Javascript disabled
Thanks in advance
Depending on server-side language, the submit button being disabled could cause problems. This is because disabled elements are not POSTed to the server. Languages like ASP.NET require the button value to be submitted so it knows what event handler to fire. What I usually do is hide the submit button, and insert a disabled dummy button after it, which appears identical to the user. Then in your onsubmit handler, you can return false and submit the form programmatically...
$('#mail-form').submit(function(){
var btn = $('#send-emails');
var disBtn = $("<input type='button'/>").val(btn.val()).attr("disabled", "disabled");
btn.hide().after(disBtn);
this.submit();
return false;
});
Contradictory to the other up-voted answers, please note that you do not need to explicitly return true from your submit handler for natural form submission: http://jsfiddle.net/XcS5L/3/
I assume this means you are depending on the value of the submit button to service the request? That is you are checking
$_REQUEST['send_emails'] == 'Send';
This is not good practice. You should never depend on the value of the submit button because that is the just what is displayed to the user. Instead, you should add a hidden input that contains the event you want to fire. After the form is submitted, you don't need to care what the value of the submit button is and you can disable it. All other non-disabled data in the form is still submitted.
You can indeed force the submission after disabling the button.
$(function () {
$("#mail-form").submit(function () {
$("#send-emails").attr('disabled', 'disabled');
window.location = '?' + $("#mail-form").serialize() + '&send_mails=Send';
return false;
});
});
Server side set a $_SESSION variable that keeps track of the last time they made a submission and block submissions within a certain time.
<?php
session_start();
if (isset($_REQUEST['send_emails'])) {
if (isset($_SESSION['mail_sent'])
&& strtotime($_SESSION['mail_sent']) < strtotime('5 seconds ago')
) {
redirect_to_thanks();
}
do_post();
}
function do_post() {
if (do_validate()) {
$_SESSION['mail_sent'] = time();
redirect_to_thanks();
}
else {
yell_at_user_a_lot();
}
}
?>
You have to return true; You could try this if u want a simple button to submit the form.
$(function(){
$('#submitID').one('click',function(){
$('#formTobeSubmitted').submit();
$(this).attr('disabled','disabled');
})
});
On server side, generate a random number into each form, store the number when the form is submitted, and discard the submit if that number has already been stored earlier. When the user has disabled javascript, this is the best you can do. (Concurrency issues can be tricky as the two identical requests are handled at the same time - make sure you use some sort of locking mechanism, such as a table with a unique field or the flock() command in PHP.)
On browser side, just set a flag when the form is submitted, and discard all later submits:
$('#mail-form').submit(function() {
if ($(this).data('submitted') {
return false;
} else {
$(this).data('submitted', true).addClass('submitted');
}
});
You can use the submitted class to make the buttons gray or something. This has a few advantages to simply disabling them; Josh already said one. Another is that Firefox likes to remember disabled states when you hit refresh, which can cause your users getting stuck in certain situations.