I'm using a JQuery Ajax call to send mails.
The php side of this call send mail, one at a time, in a loop.
When the loop is finished it returns some data (message, some html..) to the js script.
It works fine.
To improve the comfort of the user while waiting, I plan to use a progress bar. So I modify both the php side and the js side.
On the php side I include a "return" statement of a mail counter, inside the loop.
On the js side I added a 'xhr' parameter to my Ajax call to listen the returned value of the counter.
HERE is my problem : Js Debug return :
xhr <exception>: TypeError
message: "xhr.responseText.addEventListener is not a function"
I can't add a listener to the vale returned par the counter,
The same result by changing 'responseText' to 'response'.
Is it about 'responseText' or 'addEventListener' ?
Did someone can help ?
The complete JS code :
function DiffuseOffre(envoi, tab, paquet, dest) {
//$('#cover-spin').show(0);
var server = '/Admin/Offres/DiffuseOffre.php';
$.ajax({
url: server,
type: 'Post',
dataType: 'json',
data: {
envoi: envoi,
tab: tab,
paquet: paquet,
dest: dest
},
xhr: function() {
$("#xhr-rep").show(0);
var xhr = new window.XMLHttpRequest();
xhr.response.addEventListener("progress", function(evt) {
$("#xhr-rep").text(evt.text);
})
},
success: function(msg) {
//$('#cover-spin').css("display", "none");
$('#xhr-rep').css("display", "none");
if (msg.hasOwnProperty('erreur')) {
$("#dialog-erreur").html(msg.erreur);
$("#dialog-erreur").dialog("open");
$("#dialog-erreur").dialog({
width: '600px',
title: msg.title
})
} else {
$("#dialog-message").html(msg.message);
$("#dialog-message").dialog("open");
$("#dialog-message").dialog({
width: '600px',
title: msg.title
})
if (paquet == 1) {
$("#envoi_" + dest).remove();
$("#diffuser").remove();
}
if (msg.hasOwnProperty('encours')) {
$("#en_cours").html(msg.encours);
}
if (msg.hasOwnProperty('fieldset')) {
$("#" + msg.fieldset).remove();
}
}
}
})
}
Related
I am trying to display a loading animation and hide the search input box before the ajax request has been sent, the ".se-pre-con" element is the loader.
As you can see below I am tring to show this in the beforeSend of the ajax request. However, when the user is typing in the search box then stops for the delay specified (1000ms) the input box still displays throughout the ajax request but it is unresponsive.
Then the results are returned, and the loading animation does the fadeOut so it the show() must be triggering but the page remains unchanged until the results are returned. I want to prevent the unresponsive page effect and show a loading animation during the request. Any help is much appreciated.
$(document).ready(function() {
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
$('#search_field').keyup(function() {
var target = $(this);
delay(function() {
getSearchResults(target.val());
}, 1000);
});
function getSearchResults(str) {
$.ajax({
beforeSend: function(){
$(".se-pre-con").show();
$("#search_field").hide();
},
url: "http://example.com/Search_Results.php",
dataType:"html",
data: {"search_term": str},
method: "post",
async: false,
success: function(data){
if(data !== null) {
$("#search_default").hide();
$("#search_results_wrapper").html(data);
}
$(".se-pre-con").fadeOut("slow");
$("#search_field").show();
$("#search_field").focus();
},
error: function(){
$(".se-pre-con").fadeOut("slow");
$("#search_field").show();
$("#search_field").focus();
}
});
}
});
I found the solution.
Solution
It started working when I removed the option:
async: false
I'm new to Javascript and Mootools and I was wondering if someone can help me learn by solving a problem that I currently have.
index.php has a form, which submit to it self and initiate this code
if($_POST['subbutton']=='Run')
{
$data=$object->do_compare();
}
I would like to know, how can I do a mootool ajax function, that will send the post['run]'
to a php script file ( data.call.php ) where the object reside and have it run.
however, I don't want any respond from data.class.php, as that object writes it's results to a txt file (data.txt)
the 2nd part,
would be an ajax function (that also run at the same time as the first ajax function) and reads a php file, every 5 seconds and bring the data back to index.php
so the squence of operations will be
index.php
form get clicked and start 2 ajax functions.
the first one, only submit the POST['run'] to a php script.
the second function, will go to another php file and get a respond from it every 5 seconds.
I didn't test the below, so use at your own risk. But that's pretty much the gist of it.
_form.addEvent('submit', function(event) {
// your first call
new Request.JSON({
url: "your-first-rpc",
data: {
subbutton: "Run"
},
onSuccess: function(response) {
// handle response here.
}
}).post();
// your second call which runs every 5 secs.
(function() {
new Request.JSON({
url: "your-second-rpc",
data: {
subbutton: "Run"
},
onSuccess: function(response) {
// handle response here.
}
}).post();
}).periodical(5000);
});
<script type="text/javascript">
window.addEvent('domready', function() {
$('dbform').addEvent('submit', function(e)
{
new Event(e).stop();
var intervalId =setInterval(function(){
var Ajax2 = new Request(
{
url: '/tools/getdata.php',
method: 'post',
data: 'read=true',
onComplete: function(response)
{
$('21').set('text', response);
}
}
).send();},1000);
var postString = 'subbutton=' + $('subbutton').value;
var Ajax = new Request({
url: '/tools/getdata.php',
method: 'post',
data: postString,
onRequest: function()
{
$('message').set('text', 'loading...');
},
onComplete: function(response)
{
$('message').set('text','completed');
clearInterval(intervalId);
},
onFailure: function() {
$('message').set('text', 'ajax failed');
}
}).send();
});
});
</script>
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.
PROBLEM SOLVED
updated the jscrollpane to the latest version which support jquery 1.8 !
https://github.com/vitch/jScrollPane/blob/master/script/jquery.jscrollpane.min.js
I'm trying to refresh a div with content for a certain period. It will fire an Ajax GET call to a php script which render the content. For the first time ajax GET called, the ScrollPane is there, but for the second time Ajax GET(refresh) JScrollPane disappeared. Any how to reinitialize the jscrollpane?
function getActivity(callback)
{
$.ajax({
url: '../../views/main/activity.php',
type: 'GET',
complete: function(){
$('#activityLineHolder').jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
//autoReinitialize = true
});
},
success: function(data) {
var api = $('#activityLineHolder').jScrollPane(
{
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
}
).data('jsp');
api.getContentPane().html(data);
api.reinitialise();
}
});
setTimeout(callback,10000);
}
$(document).ready(function(){
(function getActivitysTimeoutFunction(){
getActivity(getActivitysTimeoutFunction);
})();
});
Right now, my scrollpane is there after every Ajax call, but it shows buggy, the jscrollpane will keep moving left after every Ajax Call and slowly, it will hide the content. How is this happened?
foreach ($list as $notification) {
echo "<div class='feeds' id='$notification->notification_id'>";
$userObj = $user->show($notification->added_by);
echo $userObj->first_name.":<span class='text'>".$notification->activity."</span>";
echo " <span class='time'>".$notification_obj->nicetime($notification->created_at)."</span>";
echo "</div>";
}
something like this , that is my activity.php
here is my screenshot , anyone pls do help me #_#
http://img31.imageshack.us/img31/6871/jscrollpane.png
change the order of your commands. make a global variable that caches the ID like this:
var $activity, $activity_pane; // outside the dom ready
function getActivity(callback){
$.ajax({
url: '../../views/main/activity.php',
type: 'GET',
success: function(data) {
$activity_pane.html(data);
}
});
setTimeout(callback,10000);
}
$(function(){
$activity = $('#activityLineHolder');
$activity.jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
autoReinitialise: true
});
$activity_pane = $activity.data('jsp').getContentPane();
(function getActivitysTimeoutFunction(){
getActivity(getActivitysTimeoutFunction);
})();
});
My understanding is that a callback should be executed when the code within your method completes. If you are then wanting to run the getActivity() method again, shouldn't that be used in setTimeout(). Something like this:
function getActivity(callback)
{
$.ajax({
url: '../../views/main/activity.php',
type: 'GET',
complete: function(){
$('#activityLineHolder').jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
//autoReinitialize = true
});
},
success: function(data) {
$('#activityLineHolder').html(data);
}
});
setTimeout(function(){getActivity(callback);},10000);
if($.isFunction(callback)) {
callback();
}
}
I just take a look at http://jscrollpane.kelvinluck.com/ajax.html
I had tried and works. i change setTimeout into setInterval (function from scrollpane).
you can try this (i had tested)
$(document).ready(function(){
var api = $('#activityLineHolder').jScrollPane(
{
showArrows:true,
maintainPosition: false,
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12,
autoReinitialise: true
}
).data('jsp');
setInterval(
function()
{
$.ajax({
url: '../../views/main/activity.php',
success: function(data) {
api.getContentPane().html(data);
}
});
},
10000
);
});
I've faced this problem before, here is a snippet so you can get the idea. Good luck!
attachScroll = function(){
return $('.scroll-pane').jScrollPane({
verticalDragMinHeight: 17,
verticalDragMaxHeight: 17,
showArrows: true,
maintainPosition: false
});
}; // in this var I store all settings related to jScrollPane
var api = attachScroll().data('jsp');
$ajaxObj = $.ajax({
type: "GET", //set get or post
url: YOUR_URL,
data: null,
cache: false, //make sure you get fresh data
async: false, //very important!
beforeSend: function(){
},
success: function(){
},
complete: function(){
}
}).responseText; //$ajaxObj get the data from Ajax and store it
api.getContentPane().html($ajaxObj); //insert $ajaxObj data into "api" pane previously defined.
api.reinitialise(); //redraw jScrollPane
You can define the ajax call as a function and put it into a setInterval.
An example from official docs can be found here
Hope it helps!
Well I suppose that your HTML content coming from AJAX is long and you have problem with decreasing area size because it takes some time to render content by .html():
api.getContentPane().html(data);
And when it goes to the next line api.reinitialise() - HTML rendering isn't complete yet, but jScrollPane already catches current DIV width / height, initializes by those width / height, and then remaining html content is being inserted - and it appears outside of jScrollPane boundaries.
Read similar question: Wait for jquery .html method to finish rendering
So my adice:
1) Add a DIV at the end of your PHP code which will mark end of HTML coming from Ajax:
foreach ($list as $notification) {
...
}
echo '<div id="end-of-ajax"></div>';
2) Add periodical (200ms) check for "end-of-ajax" in your JS code - when it finds the end is reached, it calls for api.reinitialise():
var timer = setInterval(function(){
if ($("#activityLineHolder").find('#end-of-ajax').length) {
api.reinitialise();
clearInterval(timer);
}
}, 200);
EDIT
This is full JavaScript code:
function getActivity()
{
$.ajax({
url: '../../views/main/activity.php',
type: 'GET',
complete: function(){
$('#activityLineHolder').jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
//autoReinitialize = true
});
},
success: function(data) {
var api = $('#activityLineHolder').jScrollPane(
{verticalDragMinHeight: 12,verticalDragMaxHeight: 12}
).data('jsp');
api.getContentPane().html(data);
var timer = setInterval(function(){
if ($("#activityLineHolder").find('#end-of-ajax').length) {
api.reinitialise();
clearInterval(timer);
}
}, 200);
}
});
}
$(document).ready(function(){
setInterval(getActivity,10000);
});
Im not sure about what your content is but just make sure that you reset the widths and heights accordingly before reinitlizing. as i had the same issue, and that was the problem
var origHeight =$('#GnattChartContainerClip').height();
var GanttChart = $('#EntireGnattWrapper').get(0).GanttChart;
$('#GnattChartContainerClip').find('#PaddingGnatt').remove();
$('#HeadersCol').find('#PaddingHeaders').remove();
var pane = $('#GnattChartContainerClip');
$('#GnattChartContainerClip').height(origHeight+height);
$('#GnattChartContainerClip').append('<div id="PaddingGnatt" style="width:'+GanttChart.TotalWidth+'px;height:25px"></div>');
$('#HeadersCol').append('<div id="PaddingHeaders" class="header" style="height:25px"></div>');
var paned = pane.data('jsp');
paned.reinitialise();
How can I use jQuery to constantly run a PHP script and get the response every second and also to send small bits of data on mouse down to the same script?
Do I really have to add some random extension just to get such a simple timer to work?
To iterate is human, to recurse divine.
-L. Peter Deutsch
var req = function () {
$.ajax({
url : 'http://example.com/yourscript.php',
complete : function () {
req();
}
});
};
req();
In case it's not obvious, the above will make a new request as soon as the previous one completes, forever. You could also set a 1 second delay between requests as follows:
var req = function () {
$.ajax({
url : 'http://example.com/yourscript.php',
complete : function () {
setTimeout(function () {
req();
}, 1000);
}
});
};
req();
function doAjax(data){
$.ajax({
type: "POST",
data: data,
url: 'http://example.com/yourscript.php',
});
}
// Set interval
setInterval('doAjax()',1000);
// Set event handler
$(document).mousedown(function(){
doAjax({key: 'value'});
});
You could replace $(document) with an actual element if you don't want to capture clicks on the whole page.
You can do a lot more with the ajax function if you are looking for callbacks etc:
http://docs.jquery.com/Ajax/jQuery.ajax
//All pings you need:
ping.pushCallback(function() { YourCallback(); });
$.data(document.body, 'data_ping', ping);
//------------------------------------------------------
//Script
$.ping = function(url, options) {
this.url = url;
this.options = $.extend({
delay: 2000,
dataType: 'json',
timeout: 10000,
data: {},
callbacks: []
}, options);
this.queue();
};
$.ping.prototype = {
queue: function() { var self = this;
setTimeout(function() {
self.send();
}, self.options.delay);
},
send: function() { var self = this;
$.ajax(self.url, {
success: function(data) {
for (var i in self.options.callbacks) {
self.options.callbacks[i](data);
}
},
complete: function() {
self.queue();
},
dataType: self.options.dataType,
data: self.options.data,
type: "GET",
cache: false,
timeout: self.options.timeout
});
},
setData: function(key, value) {
this.options.data[key] = value;
},
pushCallback: function(callback) {
this.options.callbacks.push(callback);
}
};
You can put the code for pinging the server in a function, then do something like this:
setInterval('ping()',1000); //this will ping 1000 milliseconds or 1 second
You don't have to add some random extension. There are native javascript functions setInterval and setTimeout for doing stuff on set intervals. You would probably want to do something like
function ajaxPing() {
...
}
setInterval("ajaxPing()", 1000);
$(element).mousedown(ajaxPing);
On the other hand, if you really want to do the pinging every second, it would probably be sufficient to just store your data in variables on mousedown and submit it on next ping (that will happen in less than a second).