Show progress on Jquery ajax call for sending multiple email - php

I'm using ajax to send a single email to all my clients (example before christmas).
Here's the ajax script
$(function () {
$("#mktg_submit").on("click",function( event ) {
event.preventDefault();
console.log($("#mktg").serialize());
$("#mktg_esito").empty();
$("#mktg_esito").append("<img src='images/loading.gif' alt=loading title=loading />");
$.ajax({
type : 'POST',
url : 'json/mktg.php',
data : $("#mktg").serialize(),
dataType : 'json',
encode : true
})
.done(function(data) {
$( "#mktg_esito" ).empty();
console.log(data);
if ((data)["success"]===false) {
$( "#mktg_esito" ).append("<div class='alert alert-danger'>"+(data)["errors"]+"</div>");
} else {
$("#mktg_esito").append("<div class='alert alert-success' id='mktg_mess'><strong>Ben fatto!</strong> Email inviate correttamente.</div>");
$.each((data)["email"], function( i, val ) {
$( "#mktg_esito" ).append("<p>Email inviata a: <b>"+val+"</b></p>");
});
}
$("#mktg_mess").show().delay(1000).fadeOut();
});
});
});
Whith this I only see the loading image when the script was launched and I see the result only when all finish. When I send 1.000 email I can't see the progress of the work, can anyone help me to use the best way to see the progress of the sending?

Use the xhr object and attach an event listener to the progress event. See the reference
Add a div progress to your html
<div class="progress"></div>
<style>
.progress {
width: 0;
height: 4px;
background: black;
transition: width .3s linear;
}
</style>
Then change your ajax request with something like this :
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
if (percentComplete === 1) {
$('.progress').fadeOut();
}
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
}
}, false);
return xhr;
},
type: 'POST',
url: "your-url",
data: data,
success: function (data) {}
});

Related

How to properly showing progressbar with ajax php and mysql

I am trying to query a large data from the database and I wish to display a progress bar. The code below returns data info from the server but the progress bar just jumps to 100% while the Ajax is still querying data.
I guess the proper way is to fake the progress bar timer or possibly make a timely ajax call eg per seconds to update the progress bar. Can someone help me out with my issue? Thanks
Below is the working code so far
<html>
<head>
<script src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function (e) {
function pf(event) {
if (event.lengthComputable) {
var percentComplete = Math.round((event.loaded/event.total)*100);
$(".progressbar").width(percentComplete + '%');
$(".progressbar").html('<span>' + percentComplete +' %</span>')
$(".progressbar").html('<span> ' + percentComplete +'% Completed</span>')
}
};
$("#sForm").on('submit',(function(e) {
e.preventDefault();
$('.progressbar').css('width', '0');
$.ajax({
url: "qdata.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", pf, false);
return xhr;
},
success: function(data)
{
if(data.trim() == "good"){
alert('completed now');
}
},
error: function()
{
}
});
}));
});
</script>
</head>
<body>
<div class="progressbar"></div>
<form id="sForm" action="qdata.php" method="post">
<div id="resultdata"></div>
<input type="submit" value="Submit now" />
</form>
</body>
</html>
qdata.php
// This is just sample db
//dbconfig.php
$result = $db->prepare('SELECT fullname FROM users');
$result->execute(array());
$count = $result->rowCount();
while ($row = $result->fetch()) {
$name=htmlentities($row['fullname'], ENT_QUOTES, "UTF-8");
}
echo 'good';
you can show percentage of progress in xhr as
xhr: function () {
//upload Progress
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//update progressbar
console.log('percent', percent);
$('.progressbar').css("width", percent + '%');
}, true);
}
return xhr;
},

PHP Streaming and jQuery

What is the best way to display or deal with a large result on success while waiting for PHPto render that result. I would like to use jQuery to submit a form, have PHP process it, and give output/feedback to users while they wait (either in a div or an iframe...in the example below I use an iframe).
I have the backbone of the xhr version that I found online, but I was wondering if there is a better way (I am aware that there is jquery mixed into this:
function submitForm(){
$('#report_iframe').attr('src','/tests/stream_ajax/blank_iframe.php');
$("#report_modal").modal({backdrop: "static"});
count=1;
xhr = new XMLHttpRequest();
xhr.open("GET", "/folder/ajax_result.php", true);
xhr.onprogress = function(e) {
count = count +1;
$( "#report_iframe" ).contents().find( "#content_loader" ).text('this is jquery count' + count);
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
//console.log("Complete = " + xhr.responseText);
// alert("complete");
document.getElementById("report_iframe").srcdoc=xhr.responseText;
}
}
xhr.send();
};
Any help appreciated. Thanks.
J Doyle
Anyway you are using JQuery. Why don't you use JQuery ajax ?
$.ajax({
cache: false,
async: true,
type: "GET",
url: '/folder/ajax_result.php',
beforeSend:function()
{
count = count +1;
},
success:function(response)
{
document.getElementById("report_iframe").srcdoc=response;
}
});
I agree with #Nandan, you should use JQuery Ajax, now for the part of the progress feedback you should add an EventListener for the xhr object and display it in your frame, it would be something like this:
$.ajax({
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Download progress
xhr.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var count = evt.loaded / evt.total;
$("#content_loader").html('this is jquery count ' + count*100);
}
}, false);
return xhr;
},
type: 'GET',
url: "/folder/ajax_result.php",
data: {},
success: function(data){
//Do something
}
});
For a better explanation and more information:
Click here
Or here
UPDATE:
You could also try something like this, it works well for download progress
$.ajax({
type: 'GET',
url: "/folder/ajax_result.php",
data: {},
xhrFields: {
onprogress: function (e) {
if (e.lengthComputable) {
$("#content_loader").text("this is jquery count " + e.loaded / e.total * 100 + "%");
}
}
},
success: function(data){
//Do something
}
});

How to disable drag and drop and browse events while an ajax request is in process?

I want to prevent the user to stop selecting or drag and drop while the previous ajax request is in process.
How can i do this...
Here is the code js code :
#drag is the div id of drag and drop area
$( '#drag ' ).bind( 'dragover',function(event) {
event.stopPropagation();
event.preventDefault();
});
$( '#drag ' ).bind( 'drop',function(event) {
event.stopPropagation();
event.preventDefault();
if( upfiles == 0 )
{
upfiles = event.originalEvent.dataTransfer.files;
console.dir(upfiles);
upfiles = Array.prototype.slice.call(upfiles, 0);
}
else {
if(confirm( "Drop: Do you want to clear files selected already?" ) == true) {
upfiles = event.originalEvent.dataTransfer.files;
upfiles = Array.prototype.slice.call(upfiles, 0);
$('#fileToUpload').val('');
}
else
return;
}
$( "#fileToUpload" ).trigger( 'change' );
});
after clicking on upload button:
$("#upload_btn").click( function() {
if ( upfiles ) {
$( '#fileToUpload' ).trigger('upload'); // trigger the first 'upload' - custom event.
$(this).prop("disabled", true);
}
});
Here is the ajax request :
$( '#container' ).on( 'upload', '#fileToUpload' , function( ) {
if ( typeof upfiles[count] === 'undefined') return false;
var data = new FormData();
var fileIn = $( "#fileToUpload" )[0];
if( !upfiles )
upfiles = fileIn.files;
$(upfiles).each(function(index, file)
{
data.append( 'file'+index, file );
});
var request = $.ajax({
url: 'files.php',
type: 'POST',
data: data,
cache: false,
contentType: false,
processData: false,
beforeSend: function( ) {
$(".progressbar").show();
},
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener( 'progress', showProgress, false);
}
return xhr;
},
success: function(data){
if( percentComplete <= 100 ) {
$('#pb div').animate({ width: '100%' }, { step: function(now) {
$(this).text( Math.round(now) + '%' );
}, duration: 10});
}
$('#uplcomp').append( data );
}
});
How can i prevent the user while the previous files upload is in progress.
Updated
ok got it upto some extent (but this is also not a good idea, user can add div back from the firebug and send files again)
i have used
$( document ).ajaxStart(function() {
$( "#total" ).remove();
});
and in ajax start :
$(document).ajaxStop( function( ) {
//how can i add div back say : add <div id='total'></div> after <div id='someid'></div>
});
Is there any possibility that i can stop second ajax request while the first ajax is in process?
Apart from enabling/disabling drag and drop while ajax is in progress, I believe a better solution will be to show an transparent or translucent overlay which covers that area and prevent the user from selecting any draggable.
For disabling/enabling using jquery:
Use $( "#total" ).draggable( "disable" ); inside beforeSend() function of ajax.
Use $( "#total" ).draggable( "enable" ); inside success() of function ajax
Using CSS:
demo: http://jsfiddle.net/lotusgodkk/GCu2D/184/
CSS:
.checked {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
background:#BFBFBF;
opacity:0.5;
text-align:center;
}
.checked div {
margin:0 auto;
top:50%;
left:50%;
position:absolute;
}
HTML:
<div class="checked">
<div>Please wait...</div>
</div>
Just toggle the hide/show during ajax
Use $('.checked').show(); in beforeShow() and $('.checked').hide(); in success()
Finally i have used
if($.active === 0)
{
call ajax
}
else
{
alert("please wait previous request is in process");
}

AJAX Calling Issue

I downloaded the script from here
http://www.webresourcesdepot.com/fly-to-basket-effect-with-jquery/
its good but some bugs like
Double Click => 3 Items add to basket
Tripple Click => 7 Items add to basket
i was trying to fix it but still cant get something .. then i see this link Disable Link while animated Basket
but i can understand where i place this code.. anybody help me to fix it please ...
$(document).ready(function(){
$("#basketItemsWrap li:first").hide();
$(".productPriceWrapRight a img").click(function() {
var productIDValSplitter = (this.id).split("_");
var productIDVal = productIDValSplitter[1];
var productX = $("#productImageWrapID_" + productIDVal).offset().left;
var productY = $("#productImageWrapID_" + productIDVal).offset().top;
if( $("#productID_" + productIDVal).length > 0){
var basketX = $("#productID_" + productIDVal).offset().left;
var basketY = $("#productID_" + productIDVal).offset().top;
} else {
var basketX = $("#basketTitleWrap").offset().left;
var basketY = $("#basketTitleWrap").offset().top;
}
var gotoX = basketX - productX;
var gotoY = basketY - productY;
var newImageWidth = $("#productImageWrapID_" + productIDVal).width() / 3;
var newImageHeight = $("#productImageWrapID_" + productIDVal).height() / 3;
$("#productImageWrapID_" + productIDVal + " img")
.clone()
.prependTo("#productImageWrapID_" + productIDVal)
.css({'position' : 'absolute'})
.animate({opacity: 0.4}, 100 )
.animate({opacity: 0.1, marginLeft: gotoX, marginTop: gotoY, width: newImageWidth, height: newImageHeight}, 1200, function() {
$(this).remove();
$("#notificationsLoader").html('<img src="images/loader.gif">');
$.ajax({
type: "POST",
url: "inc/functions.php",
data: { productID: productIDVal, action: "addToBasket"},
success: function(theResponse) {
if( $("#productID_" + productIDVal).length > 0){
$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
$("#productID_" + productIDVal).before(theResponse).remove();
$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
$("#productID_" + productIDVal).animate({ opacity: 1 }, 500);
$("#notificationsLoader").empty();
} else {
$("#basketItemsWrap li:first").before(theResponse);
$("#basketItemsWrap li:first").hide();
$("#basketItemsWrap li:first").show("slow");
$("#notificationsLoader").empty();
}
}
});
});
});
$("#basketItemsWrap li img").live("click", function(event) {
var productIDValSplitter = (this.id).split("_");
var productIDVal = productIDValSplitter[1];
$("#notificationsLoader").html('<img src="images/loader.gif">');
$.ajax({
type: "POST",
url: "inc/functions.php",
data: { productID: productIDVal, action: "deleteFromBasket"},
success: function(theResponse) {
$("#productID_" + productIDVal).hide("slow", function() {$(this).remove();});
$("#notificationsLoader").empty();
}
});
});
});
I think what you might have to-do is at the end of the click event function then unbind the event http://api.jquery.com/unbind/ $(this).unbind();
You could possibly bind it again once the ajax has finished

Getting .live or .delegate or livequery plugin to keep cart alive

I have this ajax-loaded #container and I'm trying to get it to play nice with some of my plugins. So far I managed to get scrollTo and a lightbox working inside this "container of death" using jquery.live but no luck with my fancy "add to cart" buttons. I've been playing around with .delegate, the livequery plugin, etc., for a few days now but I'm really not advanced enough to figure out what goes where. (I have a pretty shallow understanding of what I'm doing.)
Here's my shopping cart plugin, it's fairly small and straightforward. Can you give suggestions on what (.live, .delegate, or .livequery, or perhaps something else entirely) should be inserted where?
(Note: shopme p = the add to cart buttons, which need to be inserted inside the ajax-loaded "container of death." The rest of the cart exists outside said container and works fine since it's not ajax'ed in.)
$(document).ready(function(){
$('.wooo').bloooming_shop();
$('body').append('<div id="panel"><div id="panelcontent"></div><div class="panelbutton" id="hidepanel" style="display: none;"><a><font class="cartfont2">hide cart</font></a></div></div><div id="showpanel" class="panelbutton" style="display: visible;"><a><font class="cartfont">shopping cart</font></a></div><div id="btntarget"></div>');
$('#panelcontent').hide();
$.ajax({
type: "GET",
url: "/wooo/cart.php",
async: false,
dataType: "html",
success: function(html){
$('#panelcontent').html(html);
}
});
$(".panelbutton").click(function(){
$("#panel").animate({
height: "200px"
}, "fast",function(){
$('#panelcontent').show();
});
$("#hidepanel").fadeIn();
$("#showpanel").fadeOut();
});
$("#hidepanel").click(function(){
$("#panel").animate({
height: "0px"
}, "fast", function(){
$("#showpanel").fadeIn();
$('#panelcontent').hide();
});
$("#hidepanel").fadeOut();
});
// START 'ADD TO CART' BUTTONS
$('.shopme p').click(function(){
var pid = $(this).attr('rel');
$('body').prepend('<div class="shadow" id="'+$(this).attr('rel')+'_shadow"></div>');
var shadow = $('#'+pid+'_shadow');
shadow.width($(this).parent().css('width')).height($(this).parent().css('height')).css('top', $(this).parent().offset().top).css('left', $(this).parent().offset().left).css('opacity', 0.5).show();
shadow.css('position', 'absolute');
shadow.animate( {
width: $('#btntarget').innerWidth(),
height: $('#btntarget').innerHeight(),
top: $('#btntarget').offset().top,
left: $('#btntarget').offset().left
}, {
duration: 2000
} )
.animate({
opacity: 0
},
{
duration: 700,
complete: function(){
shadow.remove();
}
});
var option = $('#'+pid+' .woooptions').val();
var formData = 'pid=' + pid + '&option=' + option;
$.ajax({
type : 'POST',
url : '/wooo/cart.php',
data : formData,
success : function (html) {
$('#panelcontent').html(html);
}
});
});
$('.removeitem').live('click', function() { // .LIVE is used here
rid = $(this).attr('id');
rop = $(this).attr('rel');
var remData = 'remove=' + rid + '&rop=' + rop;
$.ajax({
type : 'POST',
url : '/wooo/cart.php',
data : remData,
success : function (html) {
$('#panelcontent').html(html);
// alert('thx');
}
});
});
}); // document
function checkOut(){
jQuery.ajax({
url: "/wooo/cart.php",
type: "POST",
data : "destroysession=true",
success: function(data, textStatus, jqXHR){
if(data){
window.location.href=jQuery('a.checkout').attr("data-href");
}else{
console.log("There is no data!")
}
},
error: function(jqXHR, textStatus, errorThrown){
console.log("AJAX ERROR: "+errorThrown)
}
});
}
/** replace ******/
jQuery.fn.bloooming_shop = function(){
this.each(function(){
var elem = $(this);
var cl = 'bt1';
var id = $(this).html();
var opt = $(this).attr('options');
var text = $(this).attr('text');
var price = $(this).attr('price');
// alert(price);
if (text == undefined) {
text = 'add to cart';
}
if (opt == 'true' && price != 'true' ) {
cl = 'bt3';
}
if (price == 'true' && opt == 'true') {
cl = 'bt4';
}
if (price == 'true' && opt != 'true') {
cl = 'bt2';
}
elem.removeClass('wooo');
elem.addClass('shopme');
elem.addClass(cl);
elem.attr('id','pid'+id);
elem.html('<p rel="pid'+id+'" class="'+cl+'">'+ text +'</p>');
// get product data
if (price == 'true' || opt == 'true') {
$.ajax({
type : 'GET',
url : '/wooo/functions.php?mode=p_data&id='+id+'&opt='+opt+'&price='+price,
success : function (html) {
elem.append(html);
if (jQuery().sSelect) {
elem.children('.woooptions').sSelect();
}
// change price
$('.woooptions').change(function(){
var selid = $(this).attr('id');
var rel = $('#'+selid+' option:selected').attr('rel');
if (rel != undefined) {
$(this).parent().children('.woooprice').html(rel);
}
});
}
});
}
});
return false;
};
How do I keep this plugin alive, even within ajax'ed-in #container? I really just need the 'add to cart' buttons (shopme p) to be in said container div. Thank you.
.live("click", function(){
instead of just click.

Categories