Reputation: 7
I am using a fullcalendar for creating schedules. What I am doing is, for each week, there must be only 3 schedules (processing date, payout date and credit date). If there are already schedules for that week, I need to prompt the user that schedules are already set. But if there's no schedule set, user can still post new schedule. I am already done with the logic of this scheduler, the only problem I have is how to disable dates between the set schedules for the week?
Example, I set 04-24-2018(processing date), 04-24-18(payout date) and 04-26-18(credit date)..
How can I disable the 04-22-18,04-23-18,04-25-18,04-27-18 and 04-28-18 on that week so that user cant create new schedules for that week?
JAVASCRIPT
select:
function (start, end, jsEvent, view, resource) {
IsDateHasEvent(start);
}
function IsDateHasEvent(date) {
var allEvents = [];
allEvents = $('#calendar').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
//alert(v.start);
//return +v.start == +date;
if (v.start <= date) {
$("#eventIsAlreadySetModal").modal();
//alert(v.start);
}
});
return event.length > 0;
}
I can get all the dates with events whenever I try to alert the value of start date. But the dates between are still not disabled.
Can someone help me through this? Thank you so much.
Full Javascript code
$(document).ready(function () {
var events = [];
var selectedEvent = null;
FetchEventAndRenderCalendar();
// ******************************************
// GET ALL SCHEDULES AND DISPLAY IN CALENDAR
// ******************************************
function FetchEventAndRenderCalendar() {
$.ajax({
type: 'GET',
url: '@Url.Action("GetSchedule")',
success: function (data) {
$.each(data, function (i, v) {
var eColor = "";
if (v.status == 'Completed')
{
eColor = '#3498DB';
}
if (v.status == 'Active') {
eColor = '#2CB05B';
}
if (v.status == 'Pending') {
eColor: '#DE6209';
}
events.push({
eventID: v.scheduleId,
title: v.processedDescription,
start: moment(v.processedDatetimeStart),
status: v.status,
color: eColor
});
events.push({
eventID: v.scheduleId,
title: v.payoutDescription,
start: moment(v.payoutDatetimeStart),
status: v.status,
color: eColor
});
events.push({
eventID: v.scheduleId,
title: v.creditDescription,
start: moment(v.creditDatetimeStart),
status: v.status,
color: eColor,
end: moment(v.creditDatetimeStart)
});
})
GenerateCalendar(events);
},
error: function (error) {
alert('failed');
}
})
}
// ******************************************
// GENERATE THE CALENDAR VIEW AND SCHEDULES
// ******************************************
function GenerateCalendar(events) {
$('#calendar').fullCalendar('destroy');
$('#calendar').fullCalendar({
contentHeight: 500,
header: {
left: 'prev,next today',
center: 'title',
right: 'month, agendaWeek, agendaDay, listWeek'
},
navLinks: true,
editable: true,
eventLimit: true,
eventColor: '#2CB05B',
droppable: false,
timeFormat: 'h(:mm)A',
timeZone: 'local',
events: events,
// **************************************
// display the saved schedule in calendar
// **************************************
eventClick:
function (calEvent, jsEvent, view) {
$("#statusLabel").text(calEvent.status);
$("#schedId").val(calEvent.eventID);
$("#schedDesc").html(calEvent.title);
$("#txtDateStart_Edit").val(calEvent.start.format("MM-DD-YYYY HH:mm A"));
$('#modalEditSchedule').modal();
if ($("#statusLabel").html() == "Completed")
{
$("#btnEditSched").hide();
}
if ($("#statusLabel").html() == "Active") {
$("#btnEditSched").hide();
}
},
// *************************************************
// select dates in calendar for posting new schedule
// *************************************************
selectable: true,
selectOverlap: true,
select:
function (start, end, jsEvent, view, resource) {
IsDateHasEvent(start);
},
// *********************************************
// disable past navigation button for past dates
// *********************************************
viewRender: function (currentView) {
var minDate = moment();
// Past dates
if (minDate >= currentView.start) {
$(".fc-prev-button").prop('disabled', true);
$(".fc-prev-button").addClass('fc-state-disabled');
}
else {
$(".fc-prev-button").removeClass('fc-state-disabled');
$(".fc-prev-button").prop('disabled', false);
}
},
// ******************************
// disable past dates in calendar
// ******************************
validRange: function (dateNow) {
return {
start: dateNow.subtract(1, 'days')
};
}
, dayClick: function (date) {
var events = $('#calendar').fullCalendar('clientEvents');
for (var i = 0; i < events.length; i++) {
//if (moment(date).isSame(moment(events[i].start))) {
if (moment(events[i].start) <= moment(date)) {
alert('with events');
break;
}
else //if (i == events.length - 1)
{
alert('none');
}
}
}
});
}
// **********************************
// show modal for adding new schedule
// **********************************
function openAddEditForm() {
$('#modalAddSchedule').modal();
}
});
function IsDateHasEvent(date) {
var allEvents = [];
allEvents = $('#calendar').fullCalendar('clientEvents');
var event = $.grep(allEvents, function (v) {
//alert(v.start);
//return +v.start == +date;
if (v.start <= date) {
$("#eventIsAlreadySetModal").modal();
//alert(v.start);
}
});
return event.length > 0;
}
Upvotes: 0
Views: 387
Reputation: 528
You need to:
Right? I'll try to solve the first part of your problem with javascript Date class. I don't know about FullCalendar, so if anyone can solve that part I would be glad, hehe.
We must check when a week starts and when it ends. Just with that we'll get ready to do some crazy stuff.
function printDate(year, month, day) {
month = (month < 10 ? '0' : '') + month.toString();
day = (day < 10 ? '0' : '') + day.toString();
return year + '-' + month + '-' + day;
}
function weekStart(dateString) {
var dateObject = new Date(dateString);
var dayOfWeek = dateObject.getDay();
if(dayOfWeek > 0) {
dateObject.setDate(day - dayOfWeek);
}
return printDate(dateObject.getFullYear(), dateObject.getMonth()+1, dateObject.getDate());
}
function weekEnd(dateString) {
var dateObject = new Date(dateString);
var dayOfWeek = dateObject.getDay();
if(dayOfWeek < 6) {
dateObject.setDate(day + (6-dayOfWeek));
}
return printDate(dateObject.getFullYear(), dateObject.getMonth()+1, dateObject.getDate());
}
function weekRange(dateString) {
return [weekStart(dateString), weekEnd(dateString)];
}
Nice, now we can get a "week range" from a date. But from that, can we get all dates of that week? Sure.
function getDatesFromWeek(wStart) {
var dates = [],
date = new Date(wStart),
count = 0;
while(count <= 6) {
date.setDate(date.getDate() + count);
dates.push(printDate(date.getFullYear(), date.getMonth()+1, date.getDate());
count++;
}
return dates;
}
Perfect. So now we should count for each range. Assuming you're receiving your info on a variable called schedules
and each schedule have an index called date
:
var weeks = {}, lockedDates = [];
for(var x in schedules) {
var week = weekRange(schedules[x].date);
var weekID = week.join('-');
if(weeks[weekID] == undefined) {
weeks[weekID] = 1;
} else {
weeks[weekID]++;
}
if(weeks[weekID] == 3) {
lockedDates = lockedDates.concat(getDatesFromWeek(week[0]));
}
}
Then you have all those dates to disable listed on lockedDates
variable in format YYYY-MM-DD
. Do you know how to do the rest?
Let's change the last part I made to this:
function Locker() {
this.dates = [];
this.weeks = {};
}
Locker.prototype.add = function(dateString) {
var wStart = weekStart(dateString);
if(this.weeks[wStart] == undefined) {
this.weeks[wStart] = 1;
} else {
this.weeks[wStart]++;
}
if(this.weeks[wStart] == 3) {
this.lock(getDatesFromWeek(wStart));
}
}
Locker.prototype.lock = function(dates) {
this.lockedDates = this.lockedDates.concat(dates);
// do something
}
var calendarLocker = new Locker();
// everytime an user add a date, call calendarLocker.add(date);
// so when it reaches the limit, the locker will call calendarLocker.lock
Upvotes: 1