How to disable dates in jQuery UI Datepicker after onChangeMonthYear - javascript

I've seen solutions using the onBeforeShowDay but that is not what I need. What I need is when changing the either Month or Year I need to get a list of dates via AJAX and then use that list to disable the days in the current month.
Example
$('#date_input').datepicker( "option", "onChangeMonthYear", function(year,month,inst) {
// Perform AJAX call and get the list
$.ajax({
url: ajaxUrl,
type: "post",
data: serializedData,
async: false,
success: function (data) {
// Here is where I want to update the display
// and use the returned data as the basis for the disabled list
// of the current month.
// Let's say:
// data = ['2015-10-15','2015-10-25','2015-10-13'];
}
});
});
EDIT
Thanks for the solution. To be specific, I was using the dynamic approach by adding the callback dynamically. Also it is important that AJAX call need to have async: false in order to get the correct data set on the array.
$('#date_input').datepicker( "option", "onChangeMonthYear", function(year,month,inst) {
// The ajax call.
});
So I just followed the answer and added:
$('#date_input').datepicker( "option", "beforeShowDay", function(date) {
// Update the list.
});
Again, much thanks!

you can still use the onBeforeShowDay, since it will get called before the datepicker is displayed, because changing months will make the datepicker to render again.
You can use an array that stores the list of dates and change this based on the result from your ajax call. e.g
//at first only september dates will be disabled.
var array = ["2015-09-23","2015-09-24","2013-09-16"];
$('input').datepicker({
onChangeMonthYear: function(year, month, inst) {
// Perform AJAX call and get the list
//override the array, and now the october dates will be disabled.
$.ajax({
url: ajaxUrl,
type: "post",
data: serializedData,
async: false,
success: function (data) {
array = data; //["2015-10-23","2015-10-24","2013-10-16"];
}
});
},
beforeShowDay: function (date) {
var string = jQuery.datepicker.formatDate('yyyy-mm-dd', date);
return [array.indexOf(string) == -1 ]
}
});
here is the working fiddle

Related

Fullcalendar eventLimittext day value

Hi I need to get eventlimittext day value.I shows and calls function when evenlimit exceed.
So I can get day value in eventLimitClick like
//in creating calendar
eventLimitClick :moreClicked,
function moreClicked(cellInfo, jsEvent) {
var event = cellInfo.date.format("YYYY-MM-DD HH:mm:ss");
console.log(event)
I just gotta get the day value which exceed the limit
eventLimitText: function (numEvents) {
//var event = cellInfo.date.format("YYYY-MM-DD HH:mm:ss");
console.log("numEvents");
console.log(numEvents);
In success i can get value but I can't get the day to pass controller with start data parameter. How can I get it
Thank you
$.ajax({
url: '/home/GetCountByDay',
type: 'POST',
dataType: 'json',
success: function (succ) {

Using ajax in a callback where the parent process itself relies on an ajax call

I'm working with an application that uses DataTables to generate a HTML table which is populated by data from an ajax request.
This is fairly simple:
var substancesTable = $('#substancesTable').DataTable({
"processing": true,
"serverSide": true,
"searching": false,
"ajax": {
"url": "/get-substances.json",
"method": "POST",
"cache": false,
"dataSrc": function (json) {
// Update non-Datatables UI elements and perform other functions based on the ajax response
$('#numSubstances').html(json.recordsTotal);
drawOptionsButton(json.isFiltering);
// Must return data for DataTables to work
return json.data;
}
},
// ...
});
There is a callback which DataTables provides, called rowCallback (https://datatables.net/reference/option/rowCallback) which allows post processing of table rows after the table has been drawn. The key thing here is that it's after the ajax request to /get-substances.json; the table must be populated with data because this callback is used to manipulate data within it at that point.
Within rowCallback I'm providing an array of row ID's in my table - that is to say ID's which correspond to <tr> elements inside #substancesTable - and I go on to expand these rows. I can do this manually by hardcoding in an array of row ID's, e.g.
var substancesTable = $('#substancesTable').DataTable({
// ...
"rowCallback": function(row) {
var id = $(row).find('td:first').text();
var index = $.inArray(id, ['4', '7']); // hardcoded array
if (index !== -1) {
var tr = $(row).closest('tr');
var row = substancesTable.row( tr );
row.child.show();
tr.addClass('active');
}
});
The array I've hardcoded means rows 4 and 7 are expanded after the table has been populated, which is equivalent to the user clicking on them.
The problem I have is that I don't want to hardcode the array. The application stores the equivalent of var index in Redis (cache) meaning that we can grab the data easily even if the user leaves the page. So I have added a second ajax request (outside the var substancesTable... block) to obtain the Redis data. This makes an ajax request to populate an array, activeRows:
var activeRows = [];
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
activeRows = data;
console.log(activeRows);
});
I understand that the nature of ajax means my code is asynchronous. In some cases the ajax request shown above will complete before the DataTable is drawn, so I get the console.log(activeRows) appearing before the table is rendered, and in other cases it happens afterwards.
What is the correct way to make this second ajax request such that the values from it can be used in place of the hardcoded array? I appreciate I will need to convert the response to an array (since it's still JSON in the console.log statement). But my question is focused on where to put this code such that it can be used reliably inside rowCallback?
I have read How do I return the response from an asynchronous call? and understand about the async nature. I can't work out how to structure this to be used in a callback that's already part of an ajax request.
The application uses DataTables version 1.10.16 and jquery 3.2.1
You can actually use the ajax option to:
Make the first AJAX request which retrieves the active rows.
Once the active rows are retrieved, make the second AJAX request which retrieves the table data.
Example: (see full code and demo here)
var activeRows = [];
function getActiveRows() {
return $.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(data){
activeRows = data;
console.log(activeRows);
});
}
function getTableData(data, callback) {
return $.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
}
$('#example').dataTable({
ajax: function(data, callback){
getActiveRows().always(function(){
getTableData(data, callback);
});
},
rowCallback: function(row, data){
...
}
});
UPDATE
In the above example, I separated the AJAX calls into two different functions mainly to avoid long indentation in the ajax option when you call the $('#example').dataTable(). The code would otherwise look like:
var activeRows = [];
$('#example').dataTable({
ajax: function(data, callback){
// 1. Retrieve the active rows.
$.ajax({
url: '/view-substance/get-active-rows',
type: 'POST',
dataType: 'json'
...
}).done(function(res){
activeRows = res;
console.log(activeRows);
}).always(function(){
// 2. Retrieve the table data.
$.ajax({
url: '/get-substances.json',
type: 'POST',
dataType: 'json',
'data': data // must send the `data`, but can be extended using $.extend()
...
}).done(callback); // and call callback() once we've retrieved the table data
});
},
rowCallback: function(row, data){
...
}
});
I used the .always() so that the table data would still be retrieved in case of failures in retrieving the active rows.
You could solve your problem with Promises. Promises are objects that help you manage and coordinate asynchronous tasks. Your case would look something like this:
var activeRows = [];
var substancesTable = $('#substancesTable').DataTable({
// ...
});
var pDataTable = new Promise(function(resolve, reject){
// you wan't to resolve just once,
// after the table has finished processing the received data.
// (You may want to change draw to an event that's more suitable)
substancesTable.one('draw', resolve);
});
var pOpenRows = new Promise(function( resolve, reject ){
$.ajax({
url: '/view-substance/get-active-rows',
method: 'post',
cache: false,
}).done(function(data) {
// you can either save your rows globaly or give them to the resolve function
// you don't have to do both
activeRows = data;
resolve( data );
});
});
// Here we basically create a third promise, which resolves (or rejects)
// automatically based on the promises in the array.
Promise.all([pDataTable, pOpenRows])
.then(function( values ){
// expand your table rows here
// Note: if you gave your rows to the resolve function you can access
// them here in values[1] (pDataTable's data would be in values[0])
});
In case you want to learn more about Promises:
https://developers.google.com/web/fundamentals/primers/promises
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://scotch.io/tutorials/javascript-promises-for-dummies
For details on browser support you may look here:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://caniuse.com/#search=Promise

BeforeShowDay doesn't changed in datepicker

I have a function to disabled specific days before show date in datepicker, but I have an error: when I call my function in first time it works, but in second call I still have the first result.
For example on the first call I have Sunday disabled, when I call the function again I have Sunday disabled too.
I see that the error is in the variable used in BeforShowDay, is still not changed just inside datepicker, but outside is changer in each call.
This is my code:
function loadFreeDays (etablissement) {
var array=[];
$.ajax({
type: "POST",
url: "/promo3/etablissments/getFreeDays/"+etablissement,
data: {'etablissement': etablissement } ,
dataType: 'json',
success: function(response){
$.each(response, function(i, value) {
array.push(value);
}),
/*console.log(" diasbled days are "+array); here variable still is changed */
$('#datepicker').datepicker({
beforeShowDay: function(date){
/* here array variable still not changed */
for (i = 0; i < array.length; i++) {
if (date.getDay() == array[i][0]) {
return [false];
}
}
var string = jQuery.datepicker.formatDate('d-m-yy', date);
var day = date.getDay();
return [true, ''];
}
});
},
error: function(x, e) { }
});
}
I solve the problem by colling $('#txtDate').datepicker("destroy"); before ajax function.
It work now.

Javascript autocomplete with ajax call order

I have simple autocomplete input field with Javascript like this:
$('#search').on('keyup', function () {
var query = $(this).val();
$.ajax({
type: "GET",
url: "/search",
data: { query: query }
}).done(function (results) {
showSearchResults(results);
});
});
Sometimes first call takes more time then second or third and results are overridden.
How can I make sure that results only from the latest successful call are displayed?
I mean if I got response from call #3 - I no longer care about calls #1 and #2 and don't want them to override results of call #3.
Ajax function is in default asynchronous it means that many of functions can run on same time. If You wrote 3 letters it will run 3 times, after 3 keyups. If you want to run function in sequence just add setting async: false.
$.ajax({
type: "GET",
url: "/search",
async: false,
data: { query: query }
}).done(function (results) {
showSearchResults(results);
});
But i think You should add some delay, so function will not run immediately after every keyup, just after last one.
I suggest that you bind an incremental id to each ajax request that you send. When you get a response, just check that it carries last given id.
let lastXHRid=0; // tracker of last sent ajax request
$('#search').on('keyup', function () {
let reqXHR = $.ajax({ // create a variable out of $.ajax returned value
type: "GET",
url: "/search",
data: { query: $(this).val() }
});
lastXHRid++; // increment the XHR counter
reqXHR.id = lastXHRid; // attach id to the request
reqXHR.done(function(results, status, respXHR) {
if ( respXHR.id == lastXHRid ){ // compare id of received and last sent requests
showSearchResults(results);
}
});
});
(Edit: I initially suggested tracking the unix timestamp of last sent request, but as #seth-battis suggested in the comments, a sequence number is far enough. As a bonus, I also debugged my sample snippet!)

A very simple JSON request with jQuery

I'm trying to get a simple JSON request working with jQuery. I want to get the premiers of new shows from Trakt (API: http://trakt.tv/api-docs/calendar-premieres), but cannot navigate through the nodes. Seems that I might be needing a date attached after the API key in the URL, but I'm not sure, since dealing with JSON is quite new to me.
$.ajax({
type: "GET",
url: [url_with_actual_api_key],
dataType: "json",
async: true,
cache: false,
success: function(data){
$.each(data, function(data, value) {
$(".title").append("<div class='item'><span>Title:</span>" + value.title + "</div>");
});
}
I'm getting UNDEFINED of course, because I'm trying to retrieve data few levels 'deeper'. Also, value.episode shows nothing, getting the title is the closest I got. My question is, how do I get the whole data from the request for each episode on API's date?
Thanks a lot and a million highfives.
You need to iterate twice, since you have an array of date, containing an array of episodes:
success: function(data){
// for each date
$.each(data, function(index, broadcastDate) {
// broadcastDate.date has the date
// broadcastDate.episodes has the show data.
$.each(broadcastDate.episodes, function(index,episode) {
// episode contains show and episode objects
$(".title").append("<div class='item'><span>Title:</span>" + episode.show.title + "</div>");
});
});

Categories