I have an issue in a Wordpress installation with a plugin. There is a calendar which you can click on a day (or a range of days) and from ajax calls through admin-ajax.php it calculates product costs.
The problem is that, when I click on a calendar cell, the admin-ajax.php is called twice. The first time for a few milliseconds and canceled immediately. Then automatically, it calls it once again and get the ajax response. When I click for a second time on a calendar cell, the admin-ajax.php is called 3 times. The first two are canceled and only the last one get a response.
I found that the code that is used for this part is the following. However, I cannot find any issue on it, even if I can see those cancelled calls on Developer console.
$('.wc-bookings-booking-form')
.on('change', 'input, select', function() {
var index = $('.wc-bookings-booking-form').index(this);
if ( xhr[index] ) {
xhr[index].abort();
}
$form = $(this).closest('form');
var required_fields = $form.find('input.required_for_calculation');
var filled = true;
$.each( required_fields, function( index, field ) {
var value = $(field).val();
if ( ! value ) {
filled = false;
}
});
if ( ! filled ) {
$form.find('.wc-bookings-booking-cost').hide();
return;
}
$form.find('.wc-bookings-booking-cost').block({message: null, overlayCSS: {background: '#fff', backgroundSize: '16px 16px', opacity: 0.6}}).show();
xhr[index] = $.ajax({
type: 'POST',
url: booking_form_params.ajax_url,
data: {
action: 'wc_bookings_calculate_costs',
form: $form.serialize()
},
success: function( code ) {
if ( code.charAt(0) !== '{' ) {
console.log( code );
code = '{' + code.split(/\{(.+)?/)[1];
}
result = $.parseJSON( code );
if ( result.result == 'ERROR' ) {
$form.find('.wc-bookings-booking-cost').html( result.html );
$form.find('.wc-bookings-booking-cost').unblock();
$form.find('.single_add_to_cart_button').addClass('disabled');
} else if ( result.result == 'SUCCESS' ) {
$form.find('.wc-bookings-booking-cost').html( result.html );
$form.find('.wc-bookings-booking-cost').unblock();
$form.find('.single_add_to_cart_button').removeClass('disabled');
} else {
$form.find('.wc-bookings-booking-cost').hide();
$form.find('.single_add_to_cart_button').addClass('disabled');
console.log( code );
}
},
error: function() {
$form.find('.wc-bookings-booking-cost').hide();
$form.find('.single_add_to_cart_button').addClass('disabled');
},
dataType: "html"
});
})
.each(function(){
var button = $(this).closest('form').find('.single_add_to_cart_button');
button.addClass('disabled');
});
And here is a screenshot from the Dev Console:
EDIT: I think I found the problem, but I am not sure. There is also this part of code which was supposed to not used at all. There is a feature for time on calendar, but it isn't activated. So, this code should not be run.
$('.wc-bookings-booking-form').on( 'date-selected', function() {
show_available_time_blocks( this );
});
var xhr;
function show_available_time_blocks( element ) {
var $form = $(element).closest('form');
var block_picker = $form.find('.block-picker');
var fieldset = $form.find('.wc_bookings_field_start_date');
var year = parseInt( fieldset.find( 'input.booking_date_year' ).val(), 10 );
var month = parseInt( fieldset.find( 'input.booking_date_month' ).val(), 10 );
var day = parseInt( fieldset.find( 'input.booking_date_day' ).val(), 10 );
if ( ! year || ! month || ! day ) {
return;
}
// clear blocks
block_picker.closest('div').find('input').val( '' ).change();
block_picker.closest('div').block({message: null, overlayCSS: {background: '#fff', backgroundSize: '16px 16px', opacity: 0.6}}).show();
// Get blocks via ajax
if ( xhr ) xhr.abort();
xhr = $.ajax({
type: 'POST',
url: booking_form_params.ajax_url,
data: {
action: 'wc_bookings_get_blocks',
form: $form.serialize()
},
success: function( code ) {
block_picker.html( code );
resize_blocks();
block_picker.closest('div').unblock();
},
dataType: "html"
});
}
Related
I need to calculate the cost of shipping without reloading the cart page. I'm trying to do this via AJAX but I did not succeed.
I started the code below and could not continue
var $warp_fragment_refresh = {
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
type: 'POST',
success: function( data ) {
if ( data && data.fragments ) {
jQuery.each(data.fragments, function(key, value){
jQuery(key).replaceWith(value);
});
jQuery( document.body ).trigger( 'wc_fragments_refreshed' );
}
}
};
jQuery( function( $ ){
$('form.woocommerce-cart-form').on('submit', function (e)
{
e.preventDefault();
$(".btn-calc-ship").addClass("loading");
var ship_calc = window.location,
form = $(this);
$(".btn-calc-shipp").removeClass("loading");
});
});
I am trying to validate part of a form, I am stuck on checking the database to see if a company name exists before submitting the form. This is a stripped down demo from the jquery ui modal from with the addition of checking if the company already exists. I am aware of SQL injection and am not doing anything about it just yet. At the moment the form won't submit as I'm missing something, I just don't know what yet.
Any help would be much appreciated.
This is what I have so far
The JS code:
$(function() {
var dialog, form,
company_name = $( "#company_name" ),
tips = $( ".validateTips" );
function updateTips( t ) {
tips
.text( t )
.addClass( "ui-state-highlight" );
setTimeout(function() {
tips.removeClass( "ui-state-highlight", 1500 );
}, 500 );
}
function checkCompany( o, n ) {
$.ajax({
type: "POST",
url: "crud.php?act=check",
data: "&company_name=" + o.val(),
success: function(response){
if(response > 0){
o.addClass( "ui-state-error" );
updateTips( n );
return false;
} else {
return true;
}
}
})
}
function addUser() {
var valid = true;
valid = valid && checkCompany( company_name, "Company Name already exists." );
if ( valid ) {
$.ajax({
type: "POST",
url: "crud.php?act=create",
data: "&company_name=" + company_name.val(),
success: function(data){
}
});
dialog.dialog( "close" );
}
return valid;
}
dialog = $( "#dialog-form" ).dialog({
autoOpen: false,
height: 350,
width: 350,
modal: true,
buttons: {
"Create an account": addUser,
Cancel: function() {
dialog.dialog( "close" );
}
},
close: function() {
form[ 0 ].reset();
allFields.removeClass( "ui-state-error" );
}
});
form = dialog.find( "form" ).on( "submit", function( event ) {
event.preventDefault();
addUser();
});
$( "#create-user" ).button().on( "click", function() {
dialog.dialog( "open" );
});
});
The php side (crud.php):
include 'connection.php';
$action = $_GET['act'];
if(isset($_POST['company_name'])){
$company_name = $_POST['company_name'];
}
switch($action){
case 'create':
$q = "INSERT INTO company_info (company_name) VALUES
('".$company_name."')";
mysql_query($q);
break;
case 'check':
$result = mysql_query('SELECT company_name FROM company_info WHERE company_name = "'.$company_name.'"');
$num = mysql_num_rows($result);
echo $num;
break;
}
CheckCompany returns nothing. You are returning true or false from success but that goes nowhere.
You need an outer deferred so you can return something from your ajax success, back through checkcompany out to your call.
Basically, checkcompany is called and exits/returns normally. SOme time later, the success function runs but that is independent because it's async. It's not part of your checkcompanmy function.
Ideally, you should trigger an event on ajax success that your element subscribes to.
Examples from comment below:
checkCompany(o,n) {
var retval = false;
$.ajax({
sync : true,
success: function(data) {
retval = true;
}
});
return retval;
}
OR asynch:
checkCompany(o,n) {
$.ajax({
success: function(data) {
$("#ID").trigger('ajsuccess.company');
}
});
}
OR using returned promise:
if (valid) {
checkCompany().done(function() {
do the secondary ajax call in here
}
}
checkCompany(o,n) {
return $.ajax();
}
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");
}
Can anybody help me with this? While alerting sData, it contains all the values I need, but when POSTing, it contains only data from current page in datatables.
var oTable;
$(document).ready
(
function()
{
$('#form0').submit
(
function()
{
var sData = $('input', oTable.fnGetNodes()).serialize().replace(/%5B%5D/g, '[]');
alert( "The following data would have been submitted to the server: \n\n"+sData );
$( {
"type": "POST",
"dataType": "html",
"url": $("#form0").attr('action'),
"data": sData,
"success": fnCallback
} );
return false;
}
);
var oTable = $('#gridtable0').dataTable(
{
"sDom": 'T<"clear">lfrtip',
"bSortClasses": false,
"sPaginationType": "full_numbers",
"fnDrawCallback": function ( oSettings )
{
/* Need to redo the counters if filtered or sorted */
if ( oSettings.bSorted || oSettings.bFiltered )
{
for ( var i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
{
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).html( i+1 );
}
}
}
}
);
}
);
Alert: (2 checkboxes checked on 1 and two on second page)
id=2205&id=2204&id=2181&id=2179
POST: (2 checkboxes checked on current page)
id=2181&id=2179
Instead of fnGetNodes, use $
Example:
var sData = $('input', oTable.$('tr')).serialize().replace(/%5B%5D/g, '[]');
jQuery(function ($) {
/* fetch elements and stop form event */
$("form.follow-form").submit(function (e) {
/* stop event */
e.preventDefault();
/* "on request" */
$(this).find('i').addClass('active');
/* send ajax request */
$.post('listen.php', {
followID: $(this).find('input').val()
}, function () {
/* find and hide button, create element */
$(e.currentTarget)
.find('button').hide()
.after('<span class="following"><span></span>Following!</span>');
});
});
});
i want to know what when i process the mysql query in the listen.php file, how deos it get the success message back, and then perform the change after?
UPDATE
PHP code:
<?php
if ( $_POST['action'] == 'follow' ) {
$json = '';
if ( $_POST['fid'] == "2" ) {
$json = array( array( "id" => 1 , "name" => "luca" ),
array( "id" => 2 , "name" => "marco" )
);
}
echo json_encode($json);
}
?>
jQuery code:
$.ajax({
type: 'POST',
url: 'listen.php',
data: 'action=follow&fid=' + 2, //$(this).find('input').val(),
success: function(data) {
var obj = $.parseJSON(data);
for ( var i = 0; i < obj.length; i++ ) {
alert( obj[i].id + ' ' + obj[i].name )
}
},
complete: function(data) {
//alert(data.responseText);
},
error: function(data) {
alert(data);
}
});
it's XMLHTTP Object that is responsible behind the scene.
your php script should output text... so lets say the query works output "YES" if it doesn't output "NO" then use this function in your $.post():
function (data) {
if(data=="YES"){
// worked
}
else{
// didn't work
}
}