Just got the FooTable responsive table plugin to work. Now I am trying to setup a PHP script to pull PostgreSQL and return a JSON encoded array.
Everything is working fine so far. I am really close to making this jQuery script work, but I'm not sure why my variables are not passing along.
Here is the script:
var columns_json;
var rows_json;
jQuery(function($){
$.ajax(
{
type: "POST",
dataType:"JSON",
url: "a.php",
data: {action: 'test'},
success: function(data)
{
columns_json = data[0];
rows_json = data[1];
console.log(columns_json);
console.log(rows_json);
},
failure: function(data)
{
alert("Something went wrong");
}
});
$('.table').footable(
{
"paging": {"enabled": true},
"filtering": {"enabled": true},
"sorting": {"enabled": true},
"columns": columns_json,
"rows": rows_json
});
});
If I look at my console, I can even see the two data arrays returned correctly... I even tried to output the data to make sure it was correct (no issue there):
console.log(JSON.stringify(columns_json))
So what I am not understanding about jQuery is:
When I update the variables I declared at the top of the scripts from within the $.ajax function, why are the JSON arrays not available at the $('.table').footable( function?
Admitting I've been only playing with jQuery for a little over a month so this is all new to me.
I did find one workaround to get this to work and that was the suggestion on this Post. I modified my script and got it to work. However the console throws a warning:
"Synchronous XMLHttpRequest on the main thread is deprecated because
of its detrimental effects to the end user's experience.".
Like always, any thoughts and suggestions are much appreciated.
Move the logic that fills your table inside the success callback.
Alternatively you can also encapsulate your logic in a function and call that function from the success callback.
The reason your code is not working, is because $.ajax is async, meaning it will not wait for the server request to finish, instead the next code will be executed immediately.
In the answer you linked you find async: false - wich is a (bad) alternative, because it will make your ajax call wait for the server response - but it will also look to the user as if the browser is frozen.
Suggestion: also show a loading animation/overlay, while you're doing ajax calls that may take a few seconds to finish.
After you've modified your code, check if your variables still need to be global.
var columns_json;
var rows_json;
jQuery(function($) {
$.ajax({
type: "POST",
dataType: "JSON",
url: "a.php",
data: {
action: 'test'
},
success: function(data) {
columns_json = data[0];
rows_json = data[1];
$('.table').footable({
"paging": {
"enabled": true
},
"filtering": {
"enabled": true
},
"sorting": {
"enabled": true
},
"columns": columns_json,
"rows": rows_json
});
},
failure: function(data) {
alert("Something went wrong");
}
});
});
Related
I have a confirmation dialog that leads to an update query when the user clicks a link.
<div class="ui-bar">
<a id="confirm" href="#" data-strid="<?php echo $str_info['str_id'] ?>">Confirm</a>
</div>
What I am looking to do is run an update query, then reload the previous page with the updated information on it.
I thought I accomplished this, but some sort of error keeps popping up in firebug and the ajax doesnt seem to be successful. The error only comes when I reload the page...and when I put a delay on it, there is no error, so I can't even read what it is.
<script>
$('#confirm').click(function (){
var str_id = $("#confirm").data("strid");
$.ajax({
type: "POST",
async: true,
url: '../../ajax/add_land',
dataType: 'json',
data: { str_id: str_id },
success: function(){
}
});
$('.ui-dialog').dialog('close')
setTimeout(
function()
{
location.reload()
}, 750);
return false;
});
</script>
Is there any good way of accomplishing this? Again, in summary, I am looking to perform an update query, then reload the last viewed page (not the dialog) so that the changed info is displayed. ../../ajax/add_land is in PHP.
There are few better ways of achieving this but that is beyond the point, in your case you should do this:
<script>
$('#confirm').click(function (){
var str_id = $("#confirm").data("strid");
$.ajax({
type: "POST",
async: true,
url: '../../ajax/add_land',
dataType: 'json',
data: { str_id: str_id },
success: function(){
$('.ui-dialog').dialog('close');
location.reload();
}
});
return false;
});
</script>
When ajax call is successfully executed it will call code inside a success callback. Ajax call is asynchronous action, that means rest of the code is not going to wait for it to finish. Because of this success callback is used. So there's need for the timeout.
One more thing, there's also an error callback, use it to debug ajax problems:
error: function (request,error) {
alert('Network error has occurred please try again!');
},
I've posted a question about it already, but I've figured out what is the exact problem. Now, I need a solution for that :)
Here's my code:
$('input[type="text"][name="appLink"]').unbind('keyup').unbind('ajax').keyup(function() {
var iTunesURL = $(this).val();
var iTunesAppID = $('input[name="iTunesAppID"]').val();
$.ajax({
type: 'POST',
url: jsonURL,
dataType: 'json',
cache: false,
timeout: 20000,
data: { a: 'checkiTunesURL', iTunesURL: iTunesURL, iTunesAppID: iTunesAppID },
success: function(data) {
if (!data.error) {
$('section.submit').fadeOut('slow');
//Modifying Submit Page
setTimeout(function() {
$('input[name="appLink"]').val(data.trackViewUrl);
$('div.appimage > img').attr('src', data.artworkUrl512).attr('alt', data.trackName);
$('div.title > p:nth-child(1)').html(data.trackName);
$('div.title > p:nth-child(2)').html('by '+data.sellerName);
$('span.mod-category').html(data.primaryGenreName);
$('span.mod-size').html(data.fileSizeBytes);
$('span.mod-update').html(data.lastUpdate);
$('select[name="version"]').html(data.verSelect);
$('input[name="iTunesAppID"]').attr('value', data.trackId);
}, 600);
//Showing Submit Page
$('section.submit').delay('600').fadeIn('slow');
} else {
$('.json-response').html(data.message).fadeIn('slow');
}
},
error: function(jqXHR, textStatus, errorThrown) {
//$('.json-response').html('Probléma történt! Kérlek próbáld újra később! (HTTP Error: '+errorThrown+' | Error Message: '+textStatus+')').fadeIn('slow');
$('.json-response').html('Something went wrong! Please check your network connection!').fadeIn('slow');
}
});
});
The Problem and Explanation:
Every time a key is triggered up it loads this ajax. If my JSON file finds a keyword it returns with error = false flag. You see, if it happens, it loads the effects, changing, etc...
The problem is that when you start to type, for example asdasdasd and just after that I paste / write the keyword there'll be some ajax queries which ones are still processing. These ones are modifying and loading the fadeOut-In effects X times.
So I'd need a solution to stop the processing ajax requests, while an other key is pressed!
Thanks in advance,
Marcell
Personally I would have the script wait so it didn't fire on each keyup. Actually I would probably use http://jqueryui.com/autocomplete/
But you can just abort the ajax before trying again.
...
var iTunesAppID = $('input[name="iTunesAppID"]').val();
if (typeof req!='undefined' && req!=null) req.abort();
req = $.ajax({
...
try adding the option async: false to your ajax this will prevent any other calls until the current one is finished.
I have a PHP populated table from Mysql and I am using JQuery to listen if a button is clicked and if clicked it will grab notes on the associated name that they clicked. It all works wonderful, there is just one problem. Sometimes when you click it and the dialog(JQuery UI) window opens, there in the text area there is nothing. If you are to click it again it will pop back up. So it seems sometimes, maybe the value is getting thrown out? I am not to sure and could use a hand.
Code:
$(document).ready(function () {
$(".NotesAccessor").click(function () {
notes_name = $(this).parent().parent().find(".user_table");
run();
});
});
function run(){
var url = '/pcg/popups/grabnotes.php';
showUrlInDialog(url);
sendUserfNotes();
}
function showUrlInDialog(url)
{
var tag = $("#dialog-container");
$.ajax({
url: url,
success: function(data) {
tag.html(data).dialog
({
width: '100%',
modal: true
}).dialog('open');
}
});
}
function sendUserfNotes()
{
$.ajax({
type: "POST",
dataType: "json",
url: '/pcg/popups/getNotes.php',
data:
{
'nameNotes': notes_name.text()
},
success: function(response) {
$('#notes_msg').text(response.the_notes)
}
});
}
function getNewnotes(){
new_notes = $('#notes_msg').val();
update(new_notes);
}
// if user updates notes
function update(new_notes)
{
$.ajax({
type: "POST",
//dataType: "json",
url: '/pcg/popups/updateNotes.php',
data:
{
'nameNotes': notes_name.text(),
'newNotes': new_notes
},
success: function(response) {
alert("Notes Updated.");
var i;
$("#dialog-container").effect( 'fade', 500 );
i = setInterval(function(){
$("#dialog-container").dialog( 'close' );
clearInterval(i);
}, 500);
}
});
}
/******is user closes notes ******/
function closeNotes()
{
var i;
$("#dialog-container").effect( 'fade', 500 );
i = setInterval(function(){
$("#dialog-container").dialog( 'close' );
clearInterval(i);
}, 500);
}
Let me know if you need anything else!
UPDATE:
The basic layout is
<div>
<div>
other stuff...
the table
</div>
</div>
Assuming that #notes_msg is located in #dialog-container, you would have to make sure that the actions happen in the correct order.
The best way to do that, is to wait for both ajax calls to finish and continue then. You can do that using the promises / jqXHR objects that the ajax calls return, see this section of the manual.
You code would look something like (you'd have to test it...):
function run(){
var url = '/pcg/popups/grabnotes.php';
var tag = $("#dialog-container");
var promise1 = showUrlInDialog(url);
var promise2 = sendUserfNotes();
$.when(promise1, promise2).done(function(data1, data2) {
// do something with the data returned from both functions:
// check to see what data1 and data2 contain, possibly the content is found
// in data1[2].responseText and data2[2].responseText
// stuff from first ajax call
tag.html(data1).dialog({
width: '100%',
modal: true
}).dialog('open');
// stuff from second ajax call, will not fail because we just added the correct html
$('#notes_msg').text(data2.the_notes)
});
}
The functions you are calling, should just return the result of the ajax call and do not do anything else:
function showUrlInDialog(url)
{
return $.ajax({
url: url
});
}
function sendUserfNotes()
{
return $.ajax({
type: "POST",
dataType: "json",
url: '/pcg/popups/getNotes.php',
data: {
'nameNotes': notes_name.text()
}
});
}
It's hard to tell from this, especially without the mark up, but both showUrlInDialog and sendUserfNotes are asynchronous actions. If showUrlInDialog finished after sendUserfNotes, then showUrlInDialog overwrites the contents of the dialog container with the data returned. This may or may not overwrite what sendUserfNotes put inside #notes_msg - depending on how the markup is laid out. If that is the case, then it would explains why the notes sometimes do not appear, seemingly randomly. It's a race condition.
There are several ways you can chain your ajax calls to keep sendUserOfNotes() from completing before ShowUrlInDialog(). Try using .ajaxComplete()
jQuery.ajaxComplete
Another ajax chaining technique you can use is to put the next call in the return of the first. The following snippet should get you on track:
function ShowUrlInDialog(url){
$.get(url,function(data){
tag.html(data).dialog({width: '100%',modal: true}).dialog('open');
sendUserOfNotes();
});
}
function sendUserOfNotes(){
$.post('/pcg/popups/getNotes.php',{'nameNotes': notes_name.text()},function(response){
$('#notes_msg').text(response.the_notes)
},"json");
}
James has it right. ShowUrlInDialog() sets the dialog's html and sendUserOfNotes() changes an element's content within the dialog. Everytime sendUserOfNotes() comes back first ShowUrlInDialog() wipes out the notes. The promise example by jeroen should work too.
The code I want to work:
$.ajax({
type: "POST",
url: "_Source/ajap/ajap.nlSrch.php",
data: { sndJson : jsonData },
dataType: "json",
processData: false,
success: function(html) {
$("#srchFrm").append(html);}
});
The code that works:
$.ajax({
type: "POST",
url: "_Source/ajap/ajap.nlSrch.php",
data: { sndJson : jsonData },
success: function(html) {
$("#srchFrm").append(html);}
});
Unfortunately when I send the first one my post data looks like this "Array ()" and when I use the later I get this "Array ( [sndJson] => [\"8\",\"3\",\"6\",\"7\"] )".
I know that there has to be a simple explanation but I haven't been able to figure it out.
Help please!
Try sending your data in a query string...
$.ajax({
type:"POST",
url:"_Source/ajap/ajap.nlSrch.php?json="+jsonData,
dataType:"json",
success: function(data) {
$("#srchFrm").append(data);}
error: function(xhr, ajaxOptions, thrownError)
{alert("Error!");}
});
You can use shorthand $.post instead of using low level ajax class --- because you don't need to advanced handling. So, this one will be great enough.
$(document.ready(function(){
$("#submit_button").click(function(){
$.post('php_script.php', {
// here's what you want to send
// important -- double quotes, 'cause It's evals as valid JSON
"var1" : "val1"
"var2" : "val2"
}, function (respond){
try {
var respond = JSON.parse(respond);
} catch(e){
//error - respond wasn't JSON
}
});
});
});
PHP code:
<?php
/**
* Here you can handle variable or array you got from JavaScript
* and send back if need.
*/
print_r($_POST); // var1 = val1, var2 = val2
?>
Back to your question,
Why my .ajax request doesn't work?
This is because JavaScript throws fatal error and stops further code execution.
You can catch and determine the error occasion, simply by adding
try {} catch(){} block to the statement you think may occur any error
When you specify dataType: json, jQuery will automatically evaluate the response and return a Javascript object, in this case an array. You're taking the result and adding it as html to #srchForm, so it does not make sense to convert it to a javascript object. Use dataType: html, or none at all.
http://api.jquery.com/jQuery.ajax/
The following examples above are not reusable. I am a huge fan of reuseable code. here is my solution.
Software design 101:
DRY Don't repeat your self. You should wrap your code into an object. This way you can call it from anywhere.
var Request = {
version: 1.0, //not needed but i like versioning things
xproxy: function(type, url, data, callback, timeout, headers, contentType)
{
if (!timeout || timeout <= 0) { timeout = 15000; }
$.ajax(
{
url: url,
type: type,
data: data,
timeout: timeout,
contentType: contentType,
success:function(data)
{
if (callback != undefined) { callback(data); }
},
error:function(data)
{
if (callback != undefined) { callback(data); }
},
beforeSend: function(xhr)
{
//headers is a list with two items
if(headers)
{
xhr.setRequestHeader('secret-key', headers[0]);
xhr.setRequestHeader('api-key', headers[1]);
}
}
});
}
};
Usage:
<script type="text/javascript">
var contentType = "applicaiton/json";
var url = "http://api.lastfm.com/get/data/";
var timeout = 1000*5; //five seconds
var requestType = "POST"; //GET, POST, DELETE, PUT
var header = [];
header.push("unique-guid");
header.push("23903820983");
var data = "{\"username\":\"james\"}"; //you should really deserialize this w/ a function
function callback(data)
{
//do logic here
}
Request.xproxy(requestType, url, data, callback, timeout, header, contentType);
</script>
I have this method that I want to run a php file using ajax and then reload the page.
function winA()
{
var x = "<?php echo $id;?>"
$.ajax({ url: 'w.php5' ,
data: { id: x },
success: function(data) {
window.location.reload()
}
});
}
This is what I have and I've looked it over endless times for flaws, made sure the php variable is reading properly and made sure the function is truly being called. The php file works properly when called w.php5?id=1
Why won't this ajax call work?
Thanks in advance for the help, Aaron.
function winA()
{
var x = "<?php echo $id;?>"
$.ajax({ url: 'w.php5' ,
data: { id: x },
success: function(data) {
window.location.reload()
}
error:function (xhr, ajaxOptions, thrownError)
{
alert(xhr.status);
alert(thrownError);
}
});
}
This way it will show alert in case of ajax error
Also, if in chrome, press the combination Ctrl+Shift+I for developer tools and check network tab to see if w.php5 is called, and what is the response. Dont know tools for other browser but there should be something like that
There are 2 alternatives.
If you want to post some other data, use this
.ajax({
type: 'POST',
url:'w.php5',
data: {id: '<?php echo $id; ?>'},
success: function(resp){
console.log(resp);
},
dataType:'json'
});
If you go this way, your ID is going to be stored in $_POST array => *$_POST['id']*
If you want to just get some data by ID you post, use this
.ajax({
type: 'GET',
url:'w.php5?id=<?php echo $id; ?>',
success: function(resp){
console.log(resp);
},
dataType:'json'
});
If you go this way, your ID is going to be stored in $_GET array => *$_GET['id']*
You're missing a semicolon here:
var x = "<?php echo $id;?>"
Should be:
var x = "<?php echo $id;?>";
//set the method
POST or GET
type:'GET'; or type:"POST"
That url is probably missing a leading forward-slash, assuming you are trying to access a url like www.myurl.com/w.php?id=5
Try
url: '/w.php?id=5',
If that doesn't work, you need to inspect the request using a developing tool within Chrome or Firefox.
You can also var_dump the $_GET or $_POST in w.php, as the response will expose the output.