Use jQuery UI datepicker with async AJAX requests - javascript

I am trying to enable specific days in a jquery-ui datepicker. So far i have set my sql scripts and json files and everything is working fine except the response time, because i've set async to false. My jquery code is.
var today = new Date();
$("#pickDate").datepicker({
minDate: today,
maxDate: today.getMonth() + 1,
dateFormat: 'dd-mm-yy',
beforeShowDay: lessonDates,
onSelect: function(dateText) {
var selectedDate = $(this).datepicker('getDate').getDay() - 1;
$("#modal").show();
$.get("http://localhost/getTime.php", {
lessonDay: selectedDate,
lessonId: $("#lesson").val()
}, function(data) {
$("#attend-time").html("");
for (var i = 0; i < data.length; i++) {
$("#attend-time").append("<option>" + data[i].lessonTime + "</option>");
$("#modal").hide();
}
}, 'json');
}
});
function lessonDates(date) {
var day = date.getDay();
var dayValues = [];
$.ajax({
type: "GET",
url: "http://localhost/getLessonDay.php",
data: {
lessonId: $("#lesson").val()
},
dataType: "json",
async: false,
success: function(data) {
for (var i = 0; i < data.length; i++) {
dayValues.push(parseInt(data[i].lessonDay));
}
}
});
if ($.inArray(day, dayValues) !== -1) {
return [true];
} else {
return [false];
}
}
Can anyone help me out? I repeat the above code is working fine but with not good response time due to async=false.
Thanks!

You are doing it all wrong. In your example, a synchronous AJAX request is fired for every day in the month. You need to re-factor your code like this (rough outline):
// global variable, accessible inside both callbacks
var dayValues = [];
$("#pickDate").datepicker({
beforeShowDay: function(date) {
// check array and return false/true
return [$.inArray(day, dayValues) >= 0 ? true : false, ""];
}
});
// perhaps call the following block whenever #lesson changes
$.ajax({
type: "GET",
url: "http://localhost/getLessonDay.php",
async: true,
success: function(data) {
// first populate the array
for (var i = 0; i < data.length; i++) {
dayValues.push(parseInt(data[i].lessonDay));
}
// tell the datepicker to draw itself again
// the beforeShowDay function is called during the processs
// where it will fetch dates from the updated array
$("#pickDate").datepicker("refresh");
}
});
See similar example here.

$.when(getdates()).done(function() {
//this code is executed when all ajax calls are done => the getdates() for example
$('#res_date').datepicker({
startDate: '-0m',
format: 'dd/mm/yyyy',
todayHighlight:'TRUE',
autoclose: true,
datesDisabled: unavailableDates,
});
});
function getdates() {
return $.ajax({
type:'GET',
url:'/available_dates',
success: function(response) {
for (let i = 0; i < response.data.length; i++) {
unavailableDates.push(response.data[i]);
}
console.log(unavailableDates);
return unavailableDates;
},
});
}

Related

Convert this LINQ code back to a Loop (or Why is this object sometimes null)

I have an Upload Button in an app that uploads a deliveries object, but sometimes the deliveries object is null when it gets to the web service.
Full code is below, but it is this bit that I am having trouble unpicking. I believe this is LINQ code, so can anyone help me convert this back into a loop so that I can begin to try and understand why the deliveries object might be null?
var deliveries = Enumerable.From(results).Select(function (r) {
r.transactionDate = r.transactionDate.format("YYYY-MM-DD HH:mm:ss");
return r;
}).ToArray();
Full code:
me.uploadClicked = function () {
playClicked();
coreViewModel.busyMessage("Processing delivery data...");
deliveryRepository.GetTodaysDeliveries(function (results) {
var deliveries = Enumerable.From(results).Select(function (r) {
r.transactionDate = r.transactionDate.format("YYYY-MM-DD HH:mm:ss");
return r;
}).ToArray();
window.setTimeout(function () {
coreViewModel.busyMessage("Uploading delivery data...");
var objUploadDeliveries = Object.create({
objStore: Object.create({
storeTypeID: coreViewModel.store.storeTypeID(),
storeID: coreViewModel.store.id()
}),
objDeliveries: deliveries
});
var comm = new URLHelper();
var xhr = $.ajax({
url: comm.hosturl() + "UploadDelivery",
type: 'POST',
beforeSend: function(xh) { xh.setRequestHeader("token", coreViewModel.token); },
data: objUploadDeliveries,
dataType: 'json',
success: function (result) {
if (!result) {
playError();
return;
}
playUploadComplete();
},
error: function (x, e) {
playError();
errorHandler(x, e);
},
timeout: 60000
});
}, 20000);
});
}
The GetTodaysDeliveries function is as follows:
GetTodaysDeliveries: function (callback) {
deliverysDatabase.GetDeliveries(function (results) {
$.each(results, function (index, result) {
result.transactionDate = moment(result.transactionDate).utc();
});
var todaysResults = Enumerable.From(results).Where(function (r) {
return moment().isSame(r.transactionDate, 'day');
}).ToArray();
return callback(todaysResults);
});
}
and the deliverydatabase.GetDeliveries function inside that is as follows:
GetDeliveries: function (callback) {
var me = this;
db.transaction(
function (context) {
context.executeSql("SELECT barcode, titleName, delivered, expected, isNews, supplier, supplierId, transactionDate FROM delivery ORDER BY titlename", [], function (context, result) {
if (result.rows.length > 0) {
var results = [];
for (var i = 0; i < result.rows.length; i++) {
results.push(result.rows.item(i));
}
return callback(results);
} else {
return callback([]);
}
}, me.ErrorHandler);
}
, me.ErrorHandler);
}
Your code snippet takes the array from results, formats the date, and then returns an array. So deliverables is the same as results but with date formatted. If delivarables is null, then results must be empty or null. You can check this by inserting a
console.log("test");
into the loop
This is the unlinqd code snippet
var deliveries = [];
results.forEach(function(item)
{
var item.transactionDate = item.transactionDate.format("YYYY-MM-DD HH:mm:ss");
deliveries.push(item);
};
I hope this clears it up.

Jquery: Unable to add Json object to Ajax request

Overview: I am making a web tool that displays the total number of movies sold by different studios on digital platform using charts(Highcharts). These charts are dynamic so the user has a list of filters he can use to change the result.
Filter 1 - Studios:
Using this filter the user can select different studios whose sales he would wish to see.
Filter 2 - Period:
This is the duration during of time for which he would want to see the sales.
It is this filter that is giveing me the problem.
Basically the selection of the period doesnot get sent with the AJAX request and hence has no effect on the chart. The default value for the period (Set using the momentjs library) also goes with the AJAX request. It is the change in the period that doesnt get added to the request.
There is no error message as such.
The Code:
$(document).ready(function(){
var btnStudiosDiv = $('#btnStudios');
var getStudios = function ()
// Get all studio's from buttons with .active class
var studios = $('button.active', btnStudiosDiv).map(function () {
return $(this).val();
}).get();
// If no studio's found, get studio's from any button.
if (!studios || studios.length <= 0) {
studios = $('button', btnStudiosDiv).map(function () {
return $(this).val();
}).get();
}
return studios;
};
var periodFrom = (moment().format('WW')-11)
var periodTo = moment().format('WW')
var output = {};
var show = function (studios) {
output['Studios'] = studios,
var per = {Period: {"From":["W" + periodFrom],"To":["W" + periodTo]}};
$.extend(output, per);
$('.list').html(JSON.stringify(output)); //Display Json Object on the Webpage
$.ajax({ //Ajax call to send the Json string to the server
type: "POST",
data: {"jsontring": JSON.stringify(output)},
url: "http://localhost:8080/salesvolume" ,
contentType: "application/json",
dataType: "json",
cache: false,
beforeSend: function() {
$('#container').html("<img class = 'ajload' src='loading.gif' />");
},
success: function(data){
alert( ) ;
$('#container').highcharts(data);
},
error: function() {
alert("Something is not OK :(")
},
});
};
var timer; //To create a time delay of 2 Secs for every selection
$(".btn").click(function () {
$(this).toggleClass('active');
// Fetch studios
var studios = getStudios();
// Remove previous timeOut if it hasn't executed yet.
if(timer)
clearTimeout(timer);
// Wait 2 sec
timer = setTimeout(function () {
// Fill list with the studios
show(studios);
},2000);
});
// Show the json on page load
show(getStudios());
//Period Selector (Template used from http://jqueryui.com/datepicker/)
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('#weekpickerFrom').datepicker('widget').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('#weekpickerFrom').datepicker( {
showOn: "button",
buttonImage: "calendar2.gif",
buttonImageOnly: true,
buttonText: "Select date",
changeMonth: true,
changeYear: true,
showWeek: true,
showOtherMonths: false,
selectOtherMonths: false,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$('#weekpickerFrom').val(date.getFullYear() + '/W'+$.datepicker.iso8601Week(new Date(dateText)));
output.Period.From = (date.getFullYear() + '/W'+$.datepicker.iso8601Week(new Date(dateText)));
periodFrom = output.Period.From //Add Period from to the Json String
if(timer)
clearTimeout(timer);
timer = window.setTimeout(function() {$('.list').html(JSON.stringify(output))},2000); //Display Json Object on the Webpage
selectCurrentWeek();
},
beforeShow: function() {
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
}).datepicker('widget').addClass('ui-weekpickerFrom');
$('.ui-weekpickerFrom .ui-datepicker-calendar tr').on('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('.ui-weekpickerFrom .ui-datepicker-calendar tr').on('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('#weekpickerTo').datepicker('widget').find('.ui-datepicker-current-day a').addClass('ui-state-active')
}, 1);
}
$('#weekpickerTo').datepicker( {
showOn: "button",
buttonImage: "calendar2.gif",
buttonImageOnly: true,
buttonText: "Select date",
changeMonth: true,
changeYear: true,
showWeek: true,
showOtherMonths: false,
selectOtherMonths: false,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = inst.settings.dateFormat || $.datepicker._defaults.dateFormat;
$('#weekpickerTo').val(date.getFullYear() + '/W'+$.datepicker.iso8601Week(new Date(dateText)));
output.Period.To = (date.getFullYear() + '/W'+$.datepicker.iso8601Week(new Date(dateText)));
periodTo = output.Period.From //Add Period to to the Json String
if(timer)
clearTimeout(timer);
timer = window.setTimeout(function() {$('.list').html(JSON.stringify(output))},2000); //Display Json Object on the Webpage
selectCurrentWeek();
},
beforeShow: function() {
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
}).datepicker('widget').addClass('ui-weekpickerTo');
$('.ui-weekpickerTo .ui-datepicker-calendar tr').on('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('.ui-weekpickerTo .ui-datepicker-calendar tr').on('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
});
It would be really helpful if someone could point out where I am going wrong.
Note: There are multiple other filter added on the tool, however for simplicity 1 have just mentioned the two important ones.
I think data should be like this
$.ajax({
type: "POST",
**data: "{\"jsontring\":" + JSON.stringify(output) + "}",**
url: "http://localhost:8080/salesvolume" ,
contentType: "application/json",
dataType: "json",
cache: false,
beforeSend: function() {
$('#container').html("<img class = 'ajload' src='loading.gif' />");
},
success: function(data){
alert( ) ;
$('#container').highcharts(data);
},
error: function() {
alert("Something is not OK :(")
},
});
In your Ajax request

method is executing before ajax call getting completed

I am trying to call a method after all ajax calls gets completed but some reason the method id getting triggered before one of the ajax call is getting completed. i tried to keep the method in ajax complete section and using $.when() and async:false but i am getting same result. I don't know if its because i am using jsonp ?
My jquery version is 1.11.0
Below is my code
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
type: "GET",
url: "crazycalls/getbbtrending.php",
// cache must be true
cache: true,
crossDomain: true,
success: function (data) {
bbTrending = data.results;
for (var i = 0; i < 4; i++) {
getProductdetails(bbTrending[i].productLink);
}
},
dataType: 'json'
});
}
function getProductdetails(pLink) {
jQuery.ajax({
type: "GET",
url: pLink,
// cache must be true
cache: true,
crossDomain: true,
success: function (data) {
pushArray(bbProductD, data);
},
dataType: 'jsonp'
});
}
function pushArray(array1,data1)
{
array1.push(data1);
}
// this function is executing before pushArray(array1,data1)
jQuery( document ).ajaxStop(function() {
displayProducts(bbProductD);
})
function displayProducts(bbProductD)
{
jQuery("#bbButtongroup").show();
var rProducts = bbProductD;
var rating;
var html = ['<div class="row">']
for (var i = 0; i < rProducts.length; i++)
{
var entry = rProducts[i];
var title = entry.name
var Tnail = entry.image;
var sPrice = entry.salePrice;
var rPrice = entry.regularPrice;
var hcode = '<div class="col-sm-6 col-md-4"><div class="thumbnail"><img style="height: 200px; width: 100%; display: block;" src=\" '+ Tnail + '\" alt="..."><div class="caption"><h3 style="font-size: 14px;">'+ title +'</h3><p><span class="label label-info"> Regular Price : '+ rPrice +'</span></p><p><span style="float: right;" class="label label-info">Sale Price :'+ sPrice +'</span></p><p>BuyView</p></div></div></div>';
html.push(hcode);
}
html.push('</div>');
document.getElementById('pContainer').innerHTML = html.join('');
}
this is how i added using $.when
jQuery.when( { getBBTrending(),getProductdetails()}).done(function() {
displayProducts(bbProductD);
});
any advice?
The asynchronous way, using async library
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
async.each(bbTrending, function(element, callback){
getProductdetails(element.productLink, callback);
}, function(err){
displayProducts(bbProductD);
});
},
});
}
function getProductdetails(pLink, callback) {
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
callback(null);
},
});
}
The promises way, using jQuery.Deferred and jQuery.when
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
var promises = [];
for (var i = 0; i < bbTrending.length; i++) {
var promise = getProductdetails(bbTrending[i].productLink);
promises.push(promise);
}
jQuery.when.apply(jQuery, promises).then(function(){
displayProducts(bbProductD);
});
},
});
}
function getProductdetails(pLink) {
var promise = jQuery.Deferred();
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
promise.resolve();
},
});
return promise;
}
The dirty way. I do not recommend this solution, it has many flaws. Try to use libraries when you need to do asynchronous stuff in order to keep your code maintainable.
var queriesCount, finishedQueriesCount;
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
queriesCount = 0;
finishedQueriesCount = 0;
for (var i = 0; i < bbTrending.length; i++) {
getProductdetails(bbTrending[i].productLink);
}
},
});
}
function getProductdetails(pLink) {
queriesCount++;
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
finishedQueriesCount++;
if(queriesCount == finishedQueriesCount) {
displayProducts(bbProductD);
}
},
});
}
In each case, I pleaced the part of your code that is not significant for the answer by //stuff
Warning This answer has no error handling, it will fail (never call displayProducts(bbProductD);) if you have an ajax error.

how can i apply if loop in datepicker

i have two date fields, if a user selects only one date then function A should get executed, else if both date are selected then function A and B should get executed. I am using jquery datepicker
These are my two onselect functions:
$(function () {
$("#SelectA").datepicker({
onSelect: function (date) {
A = $('#SelectA').val();
Method(A, "", "");
}
});
});
$(function () {
$("#SelectB").datepicker({
onSelect: function (date) {
A = $('#SelectA').val();
B = $('#SelectB').val();
Method(A, B, "");
}
});
});
The question is that how do i implement IF loop in here? And do i need to terminate functionA and re-invoke it when function B is selected?
function Method(A,B,C) {
$.ajax({
type: "POST",
url: "Services/MethodName.asmx/Method",
data: JSON.stringify({ A: A, B: B, C: C }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
place the data into a table
}
});
}
This is my datepicker:
var nowTemp = new Date();
var now = new Date(nowTemp.getFullYear(), nowTemp.getMonth(), nowTemp.getDate(), 0, 0, 0, 0);
var checkin = $('#dpd1').datepicker({
onRender: function (date) {
return date.valueOf() < now.valueOf() ? 'disabled' : '';
}
}).on('changeDate', function (ev) {
if (ev.date.valueOf() > checkout.date.valueOf()) {
var newDate = new Date(ev.date)
newDate.setDate(newDate.getDate() + 1);
checkout.setValue(newDate);
}
checkin.hide();
$('#dpd2')[0].focus();
}).data('datepicker');
var checkout = $('#dpd2').datepicker({
onRender: function (date) {
return date.valueOf() <= checkin.date.valueOf() ? 'disabled' : '';
}
}).on('changeDate', function (ev) {
checkout.hide();
}).data('datepicker');
I'm not 100% sure on what you're asking, but I think this might solve your problem (assuming the server knows how to handle blank values):
$(function () {
$("#SelectA").datepicker({
onSelect: handleSelectedDates
});
$("#SelectB").datepicker({
onSelect: handleSelectedDates
});
function handleSelectedDates(date) {
var A = $('#SelectA').val();
var B = $('#SelectB').val();
Method(A, B, "");
}
var ajaxReq;
function Method(A,B,C) {
if (ajaxReq)
ajaxReq.abort();
ajaxReq = $.ajax({
type: "POST",
url: "Services/MethodName.asmx/Method",
data: JSON.stringify({ A: A, B: B, C: "" }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
place the data into a table
}
});
}
});
Assuming you are using the jQuery datepicker (which this question has not yet been tagged), then you can simply use the onSelect method which will return the dates, which you can then check against and if statement and run your custom code.
Here is a jsfiddle. http://jsfiddle.net/xu8zZ/
$(function() {
$( "#datepicker" ).datepicker({
onSelect: function(dateText, inst) {
console.log(dateText);
console.log(inst);
}
});
});
Just look at your console when you select a date and you will see how it returns the date; at which time, you can write your condition.
Ref. http://api.jqueryui.com/datepicker/#option-onSelect
You can use one function to handle both events:
$(function () {
$("#SelectA,#SelectB").datepicker({
onSelect: function (date) {
var A = $('#SelectA').val();
if ($(this).attr("id") == "SelectB")
{
var B = $('#SelectB').val();
}
else
{
var B = "";
}
var C = "";
Method(A, B, C);
}
});
});

Accept pre-populated form field input

I just set up my date-picker to auto populate it's input field with today's date.
Normally, a user would have to select their own date and submit their selection via the enter key or, I think in my case, any key would do it.
Is there anyway to automatically do this? Since the field is pre-populated, I want the results for today's date to appear automatically on page load, without the user needing to accept the date(today) that has been pre-populated into the field.
Here's my code if it's helpful:
<script>
function displayResult() {
var k;
if (window.event) // IE8 and earlier
{
k = event.keyCode;
} else if (event.which) // IE9/Firefox/Chrome/Opera/Safari
{
k = event.which;
}
if (k == 13) //13 = 'Enter' key
{
var dt = $("#datepicker").val();
//alert(dt);
if (dt != '') {
$.ajax({
type: "POST",
url: "search_date.php",
data: "dt=" + dt,
success: function (option) {
$("#results").html(option).listview("refresh");
}
});
} else {
$("#results").html("");
}
return false;
}
}
</script>
<script type="text/javascript">
$(function () {
$("#datepicker").datepicker();
$("#datepicker").datepicker("setDate", new Date());
$('#datepicker').datepicker({
inline: true,
showOn: "button",
buttonImage: "images/calendar.gif",
showAnim: "slideDown",
changeMonth: true,
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function (dateText, inst) {
//alert($('#datepicker').datepicker( "getDate" ))
//alert("dateText: " + dateText + ", inst: " + inst);
var dt = dateText;
if (dt != '') {
$.ajax({
type: "POST",
url: "search_date.php",
data: "dt=" + dt,
success: function (option) {
$("#results").html(option).listview("refresh");
}
});
} else {
$("#results").html("");
}
return false;
}
});
$('body').ready(function(){
var dt = $("#datepicker").val();
//alert(dt);
if(dt != '')
{
$.ajax
({
type: "POST",
url: "search_date.php",
data: "dt="+ dt,
success: function(option)
{
$("#results").html(option).listview("refresh");
}
});
}
else
{
$("#results").html("");
}
return false;
});
</script>
$('body').ready(function(){
var dt = $("#datepicker").val();
//alert(dt);
if(dt != '')
{
$.ajax
({
type: "POST",
url: "search_date.php",
data: "dt="+ dt,
success: function(option)
{
$("#results").html(option).listview("refresh");
}
});
}
else
{
$("#results").html("");
}
return false;
});

Categories