Under the Hood - Calendar object - how to use the gotoDate function?

Hi to all,

I’m trying to understand the internal workings of the Calendar object in Knack. I want to add a input field of type calendar to allow direct jumping to a date, instead of clicking endlessly on the arrows to skip one month at a time. This will be added to the KTL.

FYI, the Calendar object comes from here:
FullCalendar - JavaScript Event Calendar

The gotoDate function is documented here:
Calendar::gotoDate - Docs | FullCalendar

I can see it in Knack’s code, and I can even invoke it.
This is what it looks like:

u.gotoDate = function (e, t, n) {
    e instanceof Date ? W = I(e) : C(W, e, t, n);
    L()
}

If I create a breakpoint on u.today = function() for trigger when I click on the Today button, I can set the object as a global variable temp1 and can call temp1.gotoDate(new Date(‘2018-12-31’));
Tada!!! The calendar shifts to that date!

But again, it’s always the same problem. Without a breakpoint, how do I get the calendar object “u”?
I’ve investigated Knack.views and Knack.router and more, but no success.

Normand

1 Like

Hi Normand,

You can use the gotoDate function like so:

const fc = Knack.views[viewKey].$('.knack-calendar').data('fullCalendar');
// Go to Dec. 8, 2022
fc.gotoDate(new Date(2022, 11, 8));
2 Likes

Man - you really rock!!!

I don’t know how you can figure this out, and where you get this information, but I’d sure like to know.

Thanks a million times,
Normand

While we at it, can you tell me how I can get a callback when an event is dropped (moved) in a calendar?

I can see this doc page, but not sure how to implement it.

Event Dragging & Resizing - Docs | FullCalendar

I must be very close, see this:

var calView = Knack.views[view.key].$('.knack-calendar').fullCalendar('getView');
console.log('calView =', calView);
$(calView).on('eventDrop', function (info) {
    console.log('eventDrop ' + info.dateStr);
});

But that still doesn’t work.

Norm

Normand,

You’re looking at the docs for FullCalendar v6. Knack still uses v1.

You’ll have to intercept the existing eventDrop handler than Knack has set, and then re-call Knack’s handler, a bit like this:

const fc = Knack.views[viewKey].$('.knack-calendar').data('fullCalendar');
const originalEventDropHandler = fc.options.eventDrop;
fc.options.eventDrop = function (event, dayDelta, minuteDelta, allDay, revertFunc) {
  // do your stuff here
  console.log('eventDrop', { event, dayDelta, minuteDelta, allDay, revertFunc });
  return originalEventDropHandler.call(this, ...arguments);
};

By the way, you can use that fc variable to call fullCalendar’s functions directly (ie. fc.gotoDate(new Date(...))), instead of calling with the function name as I did in the other reply. A little cleaner that way.

3 Likes

Wow again! You did it marvelously.

I spent way too many hours on this, but I learned a lot.
I can now go forward with cool new features in the KTL - thank you sir!

Norm

1 Like

Hi David,

I have another question: Do you know how can I get a callback when a view has rendered? It’s supposed to be done with the viewRender event, but it’s not in Knack.

viewRender - Docs v1 | FullCalendar

The closest I can breakpoint on is t.changeView(c) but I can’t see how I could get my callback. For example when I change the view type or when scroll through months or weeks.

I also tried to see if viewDisplay would help, based on your code, like this:

const viewDisplay = fc.options.viewDisplay;
console.log('viewDisplay =', viewDisplay);
fc.viewDisplay = function (view, element) {
    console.log('viewDisplay: view, element', view, element);
    return viewDisplay.call(this, ...arguments);
};

But the log never shows up.

Any idea?
Normand

Hi Normand,

You should be assigning your function to fc.options.viewDisplay, not fc.viewDisplay.

Note that your handler will be fired when FullCalendar’s view has rendered, which is before the events for the given view are loaded.

2 Likes

It works!!

I was so close, I can’t believe I didn’t see that one. I was getting too tired I guess.

About the callback event timing, I don’t really care since all I need to know is the new view type and visStart date like this:

//Callback when the calendar view changes type of range.
const viewDisplay = fc.options.viewDisplay;
fc.options.viewDisplay = function (view) {
    console.log('viewDisplay: view', view.name, view.visStart);
    return viewDisplay.call(this, ...arguments);
};

So all is perfect, thanks again :slight_smile:
Norm

Stupid question @hmnd - how did you know to access the .data property of Knack.views[viewKey].$(‘.knack-calendar’)?

Doesn’t appear in the console anywhere for me unless I’m not looking hard enough!

Just by reverse-engineering Knack’s rendering code. .data() is a jQuery function that allows you to store data associated with a given element, and later access it through a reference to the element. In this case, Knack uses it to keep a reference to the underlying FullCalendar instance; it’s used in some other places to keep track of filters, the inline table cell editor, and more.

2 Likes