I am having one small problem with my code. I am sending a POST request to my page, after I am done it should return "OK" meaning it worked. From inside my handler function I call set_var(data) to set my global variables text, but the problem is my print_info() returns undefined.
I've spent a lot of time on this and realize my problem has to do with scoping somehow but I am not sure how to go about fixing it. If anyone can provide any pointers, that would be great.
<?
if($_REQUEST['action'] == 'test')
{
echo "OK";
die;
}
?>
<script type="text/javascript" src="jquery-1.6.1.js" ></script>
<script type="text/javascript">
var ajax_post_result;
function set_var(data)
{
//PRINTS MY TEXT OK
alert("SET:: " + data);
//SET TO MY GLOBAL VARIABLE
ajax_post_result = data;
//ALSO PRINTS OK
alert("SET2:: " + ajax_post_result);
}
function return_handler(data, textStatus)
{
//THESE BOTH WORK ... BUT ONLY HERE AND WITHIN set_var()
//alert("1: " + data); //PRINTS WHAT I NEED
//CALL FUNCTION TO SET GLOBAL VARIABLE
set_var(data);
}
function print_info()
{
return ajax_post_result;
}
function ajax_post(file, data )
{
$.post( file, data, return_handler);
//PRINTS UNDEFINED
alert("RETURN:: " + print_info() );
}
</script>
<form id=newform name='testform'>
<input type="hidden" name="newexample" value="1">
Enter Something: <input name="something" id='something1' value="" type="text">
<input type="button" value="Submit" name="Submit" onclick="ajax_post('index.php?action=test', $('#newform').serialize() ); return false;">
</form>
AJAX requests are, as evidenced by the first A in the acronym, asynchronous. So, when you call $.post(), execution of the ajax_post function continues on its merry way more or less immediately, without waiting for the request to finish. You get to your "RETURN" alert before your return_handler has run to set the global variable.
You can use jQuery.ajax and set the async option to false, which will get you a synchronous request.
Or, and I recommend this strategy, move all the things that need to happen only after the request is done to the success handler.
Your problem is due to the asynchronous nature of AJAX.
You should do all your post AJAX processing in the callback function. Something like this (using your current functions)
$.post(file, data, function(data, textstatus) {
return_handler(data, textstatus);
alert("RETURN:: " + print_info());
});
Though you could easily combine your functions into the one closure (minus the alerts), eg
$.post(file, data, function(data, textstatus) {
ajax_post_result = data;
});
Related
I use reCaptcha+validation jQuery plugin:
<script>
$('#contact_us-form').validate({
submitHandler: function(form) {
grecaptcha.execute(); //How to run this syncly?
$(form).ajaxSubmit({ ... }); // This request without token
}
});
</script>
<form>
...
<div class='g-recaptcha' ... />
</form>
This code almost works. Almost because execute is run async and response is come after ajaxSubmit submits form data.
The work around is to assign callback property for g-recaptcha and move ajaxSubmit into that callback:
var my_callback = function() {
$(form).ajaxSubmit({ ... });
}
<div class='g-recaptcha' data-callback='my_callback'/>
But this looks hairly. Furthermore the form variable is not available from my_callback thus I can not reuse this call back between similar forms.
Is there a way to execute synchronously?
I have this html page with the form
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
</form>
And this is my javascript function to do the POST call
function post_comment(event,item_id)
{
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}}
Backend is done using Django and this is the return statement
data=simplejson.dumps(data)
return HttpResponse(data, mimetype='application/json')
The referral url is say "/xyz".
The thing is, after the form gets submitted, it is being automatically redirect to the "/status_comment/save" page instead of remaining on the same page.
I tried the get method and it works fine but not the POST method.
I tried debugging it, so changed the url in post call to the referral url, then it refreshs the page instead of doing nothing.
Also the alert() command inside the function above doesnt work, so its probably not being entered into.
Interesting thing I have noticed, when looking at the web developer console, the Initiator for the POST call in this page is being displayed as "Other" while the initiator for GET call and POST call (in other pages, where its working) is "jquery-1.8.0.min.js:2"
Any thoughts? Thanks...
First you really shouldn't try to capture the enter if you can avoid it. Use the submit binding. It makes everything more obvious and easier for your fellow developers (I bet I am not the only one who thought "What the heck is KeyCode 13?").
I'm wondering if perhaps being more explicit might help. Have you tried calling preventDefault and stopImmediatePropagation?
$('#form1').submit(function(evt) {
evt.preventDefault();
evt.stopImmediatePropagation();
// serialize and be AJAXy yada yada yada
If that doesn't work, or for some reason you prefer to handle capturing enter on your own, then you might want to have the above code in addition to your keydown handler. So it would be:
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
...
$('#form1').submit(function(event) {
event.preventDefault();
event.stopImmediatePropagation();
}
function post_comment(event,item_id)
{
event.preventDefault();
event.stopImmediatePropagation();
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}
}
Start by getting rid of the onkeydown attribute from the input:
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" />
</form>
And then simply subscribe to the .submit() event of this form using jquery and perform the AJAX request in there. Don't forget to return false from it to ensure that the default action is canceled and the browser stays on the same page:
$('#form1').submit(function() {
var str = $(this).serialize(); // Gets all the filled details
$.post(this.action, str, function(data) {
alert(data);
});
return false; // <!-- that's the important part
});
I found some close answers for this, but none of them worked in my case. I have:
Input tag:
<input name="title" id="title">
Ajax:
<script language="javascript">
function example_ajax_request() {
$('#example-placeholder').html('<p><img src="/img/ajax-loader.gif" /></p>');
setTimeout('example_ajax_request_go()', 0);
}
function example_ajax_request_go() {
$j(document).ready(function () {
var inputField = $j('#inputText').val();
$j(".button").click(function () {
$('#example-placeholder').load('preview.php?title=' + title + ' .aClass');
}
</script>
Button to call the function:
<input type="button" onclick="example_ajax_request()" value="Preview" />
I'm trying to pass 'title' var from the input tag via ajax to 'preview.php'. This code above has errors and is not running, can you suggest correct one? Thanks!
You have not put in exact error messages (from your browser's console, please put them in and update your question). I am just putting across some suggestions/improvements:
Whenever you are passing GET parameters, always URIEncode the value(the xyz and value in url?abc=xyz&blah=value). In javascript there is a function call EncodeURIComponent(..). You would use it like:
'preview.php?title=' + EncodeURIComponent(title +' .aClass')
A possible typo, you have have a space in the URL, before the + ' .aClass'. If you need one, explicitly replace it with a + or %20.
Found a way. Here it is:
<script type="text/javascript">
function example_ajax_request() {
$('#example-placeholder').html('<p><img src="img/ajax-loader.gif" /></p>');
$('#example-placeholder').load("preview.php?title="+$('#title').val());
}
</script>
Thanks!
I am having some difficulty passing a correct id function back to AJAX.
I'm creating a product bulletin generator that lets items to be added by their SKU code (which works fine). My problem is that when a bulletin is clicked on, a preview of that bulletin is loaded into a div and shows all products associated with that bulletin.
From inside those results, I am trying to add the ability to delete a product from the bulletin. The problem is that the value being passed back to AJAX belongs to the first product only. It won't send the value belonging to the particular item if it is any other item than the first one.
This is the code (belonging to main.php) that gets loaded via AJAX into a div and is looped with each product associated with a selected bulletin
echo "<form name='myDelForm'>
$news_gen_id<br>
<input type='hidden' id='delccode' value='".$news_gen_id."'>
<input type='hidden' id='deledit' value='".$edit."'>
<input type='button' onclick='ajaxDelCcode()' value='Delete' /><br></form>
</td>";
The AJAX code (on index.php, where the div that calls in main.php is also located) is this
function ajaxDelCcode(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new
ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById("ajaxMain2");
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
var deledit = document.getElementById("deledit").value;
var delccode = document.getElementById("delccode").value;
var queryString = "?delccode=" + delccode + "&deledit=" + deledit;
ajaxRequest.open("GET", "main.php" + queryString, true);
ajaxRequest.send(null);
}
//-->
</script>
Currently, using those two pieces of code, I can successfully delete only the first product. The delccode variables do not seem to change when the products are looped (although when I echo the variables during the loop, it is definitely changing to the appropriate value...it's just not passing it correctly back to AJAX.)
I tried taking the AJAX code, putting it inside the main.php product loop, and change the function name during each loop (so ajaxDelCcode$news_gen_id() for example) and also to the button itself so that it is calling the AJAX specific to it. And it works if you are visiting main.php directly...but not from index.php after main.php has been called into the div.
I can't figure out how to pass the correct looped value from main.php within the div, back to the AJAX code on index.php
Can anyone help me with this?
Thanks,
Dustin
Instead of storing the id in the input, just pass it as an argument to the function:
function ajaxDelCcode(delccode) { ...
<input type='button' onclick='ajaxDelCcode(\"".$news_gen_id."\")' value='Delete' />
Also, I'd swap the quotes if I were you. Or better yet, instead of using echo, break the PHP code and just write HTML:
<? ... ?><input type="button" onclick="ajaxDelCcode('<?= $news_gen_id ?>')" value="Delete" /><? ... ?>
What does the code you use to delete look like? Is it in the same php file as the form you posted above? If so, is the form getting submitted to itself accidentally? Like perhaps when a user presses enter while on an input type=text control? I understand that you want to do this by ajax but I am suspecting that the form is your problem.
Seconding the jQuery comment.
Here try this
1) add jquery to your document.
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
2) give your inputs name attributes
<input type='hidden' name='delcode' id='delccode' value='".$news_gen_id."'>
<input type='hidden' name='deledit' id='deledit' value='".$edit."'>
3) Use a function something like this instead of all that code above
function ajaxDelCcode() {
$.ajax({
url: "main.php",
type: "GET",
dataType: "text",
data: $("#myDelForm").serialize(),
success: function(rText) {
$("#ajaxMain2").text(rText);
}
});
}
I appreciate any and all help. I am a beginner with little jQuery/AJAX experience and I have been going crazy trying to figure out why I can't figure this out.
I'm writing a Facebook page application that has the user grant permissions and upload a video to the page. All of this works fine and dandy. This is not so much a Facebook API related issue as it is an ajax issue (at least I think).
Basically, I am trying to gain control of the page IN SOME WAY after the user uploads a video. I am using the [malsup jQuery Form Plugin][1] to have the resulting page (which is a page on Facebook displaying returned JSON values) load in a hidden iframe.
I am able to get ajaxStart to fire, and I've tested this by having it change the background color or print an alert message when I click "Upload". However, when the upload completes (and it does complete successfully), NOTHING ELSE HAPPENS. The returned JSON values load in the hidden iframe and the page sits there. I have tried getting ajaxComplete, ajaxStop and ajaxSuccess to fire, but none of them do for whatever reason.
So overall, here is what I am trying to accomplish:
- I want to redirect the user or make some hidden content appear after the file upload completes. I don't even care if there's errors. I just need SOMETHING to happen.
- I am using the jQuery Form Plugin because I am not unfortunately not advanced enough to figure out how to use that value and do something with it, but if anyone can steer me in the right direction, that would be appreciated.
And finally, here is my code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.js"></script>
<script type="text/javascript" src="http://malsup.github.com/jquery.form.js"></script>
<script type="text/javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
var options = {
target: '#output2', // target element(s) to be updated with server response
iframeTarget: '#output2',
beforeSubmit: showRequest, // pre-submit callback
success: showResponse // post-submit callback
};
// bind form using 'ajaxForm'
$('#theform').ajaxForm(options);
});
// pre-submit callback
function showRequest(formData, jqForm, options) {
return true;
}
// post-submit callback
function showResponse(responseText, statusText, xhr, $form) {
alert(responseText);
}
</script>
<script type="text/javascript">
jQuery().ready(function(){
$('body').ajaxStart(function() {
$(this).css("background-color","red");
});
$('body').ajaxSend(function() {
$(this).css("background-color","blue");
});
$('body').ajaxComplete(function() {
$(this).css("background-color","green");
});
$('body').ajaxStop(function() {
$(this).css("background-color","purple");
});
});
</script>
</head>
<body>
<?php
$app_id = "xxxxxxx";
$app_secret = "xxxxx";
$my_url = "xxxxxx";
$video_title = "xxxxxxxxx";
$video_desc = "xxxxxxxxx";
$page_id = "xxxxxxxx";
$code = $_REQUEST["code"];
if(empty($code)) {
// Get permission from the user to publish to their page.
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url)
. "&display=popup&scope=email,publish_stream,manage_pages";
$current_url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
if ($current_url != $dialog_url)
{
echo('<script>window.location ="' . $dialog_url . '";</script>');
}
} else {
// Get access token for the user, so we can GET /me/accounts
$token_url = "https://graph.facebook.com/oauth/access_token?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret
. "&code=" . $code;
$access_token = file_get_contents($token_url);
$accounts_url = "https://graph.facebook.com/me/accounts?" . $access_token;
$response = file_get_contents($accounts_url);
// Parse the return value and get the array of accounts we have
// access to. This is returned in the data[] array.
$resp_obj = json_decode($response,true);
$accounts = $resp_obj['data'];
// Find the access token for the page to which we want to post the video.
foreach($accounts as $account) {
if($account['id'] == $page_id) {
$access_token = $account['access_token'];
break;
}
}
// Using the page access token from above, create the POST action
// that our form will use to upload the video.
$post_url = "https://graph-video.facebook.com/" . $page_id . "/videos?"
. "title=" . $video_title. "&description=" . $video_desc
. "&access_token=". $access_token;
// Create a simple form
echo '<form action=" '.$post_url.' " method="POST" enctype="multipart/form-data" id="theform">';
echo 'Please choose a file:';
echo '<input name="file" type="file">';
echo '<input type="submit" value="Upload" id="button-upload" />';
echo '</form>';
}
?>
<iframe id="output2" name="output2"></iframe>
</body></html>
Thank you for your help!!
It seams you are getting an Ajax Error. I don't see any error handler in your code. Could you try to add an error handler as follows
<script>
$(document).ready(function(){
$(document).ajaxError(function(e, jqxhr, settings, exception) {
alert(exception);
})
})
</script>
I have played around with file uploads, and there are a complicated beast because of all the security that browsers have for protecting users file systems and whatnot.
On to your problem, I think that there is a good chance that your AjaxForm jQuery plugin doesn't connect properly to the global Ajax state for Jquery. Even if it did, I would say that tapping into the global Ajax state is a bad design. If you add any other ajax requests to this page, then your ajaxComplete, ajaxStop, etc. functions are going to start getting called.
Your better approach is to use the callbacks provided by the AjaxForm plugin. Lets focus on this first part of your code.
Does this work?
success: showResponse // post-submit callback
...
// post-submit callback
function showResponse(responseText, statusText, xhr, $form) {
alert(responseText);
}
If so, could you replace this:
$('body').ajaxComplete(function() {
$(this).css("background-color","green");
});
With this:
function showResponse(responseText, statusText, xhr, $form) {
$(this).css("background-color","green");
}
I believe that using the success: callback is the intended use of the AjaxForm plugin.
The jquery ajaxSend or ajaxStart throws some kind of an error and the document does not execute ajaxComplete. I tried to fix the bug for quite a while and was only able to find a workaround:
function hideAjaxIndicator() {
$('#ajax-indicator').hide();
}
$(document).ready(function () {
setTimeout(hideAjaxIndicator, 1000);
});
You can add this to .js file.