jsCalendar
jsCalendar copied to clipboard
API to access calendar columns
Currently there's no public API to access a calendar's columns (i.e. the <td>
elements resp. HTMLElement
objects). The only way to access those is currently using the (actually hidden) _active
array and iterating all columns:
var element = document.getElementById('my-calendar'),
calendar = new jsCalendar(element);
var columns = {},
previousColumns = {},
nextColumns = {},
selectedColumns = {},
currentColumn;
var rawColumns = element.querySelectorAll('tbody td');
for (var i = 0, column, date; i < calendar._active.length; i++) {
column = rawColumns[i];
date = calendar._active[i];
if (column.classList.contains('jsCalendar-previous')) {
previousColumns[date] = column;
} else if (column.classList.contains('jsCalendar-next')) {
nextColumns[date] = column;
} else {
columns[date] = column;
if (column.classList.contains('jsCalendar-selected')) {
selectedColumns[date] = column;
}
if (column.classList.contains('jsCalendar-current')) {
currentColumn = column;
}
}
}
There should be distinct APIs to return the above columns
, previousColumns
, nextColumns
, selectedColumns
and currentColumn
variables. The API should either return an object with all HTMLElement
objects indexed by timestamp (as shown above) or rather an array containing objects with Date
and HTMLElement
objects (e.g. [ { date: /* [Date] object */, element: /* [HTMLElement] object */ } ]
), depending on your preference.
Great project, I love slim but still powerful libraries like yours! :+1:
A few commits ago (d7fa9f7ea8bd4d4a603a135ef125ccfb7354b284) I added support for some undocumented handlers. One of them was dateRenderHandler
. This handler is called on every calendar update for each date on the calendar with the arguments date
, element
and info
.
date
is the javascript date object of the date
element
is the HTML element of the date (the td
of the date)
info
is an object with properties
{
"isCurrent" : true|false, // If the set date on calendar
"isSelected" : true|false, // If date is selected or not
"isPreviousMonth" : true|false, // If date is on previous month
"isCurrentMonth" : true|false, // If date is on current month
"isNextMonth" : true|false, // If date is on next month
"position" : {
"x" : 0-6, // Date x-position on calendar grid
"y" : 0-5 // Date y-position on calendar grid
}
}
In the same way, maybe we can implement a method (I am not sure about the name, and maybe with optional filter argument) which will return an array of objects like the dateRenderHandler
arguments and the one you described.
Maybe we should stick with a render
in the name to indicate that this method has to do with the HTML and the visible dates, something like getRenderedDates
.
Any thoughts on all that? Would that cover your needs? On what cases are you planning on using it? Are we missing anything? (I think getting the API right is important)
PS: Thanks for loving and using jsCalendar.
Oh, cool, I didn't know that these exist, I'm using the latest stable release (v1.4.3).
I'm using this to create JavaScript-based tooltips for some selected dates (i.e. simple event tooltips). Currently I'm achieving this by utilizing onMonthChange
and iterating all columns as shown above (with the actual tooltip creation instead of collecting the columns of course). The dateRenderHandler
perfectly matches my needs! :+1:
Some thoughts on dateRenderHandler
: It looks like a callback-based approach and thus has some limitations (like there can only be one handler at a time). I prefer event-based approaches with JavaScript; they are way more powerful and flexible. IMO the best approach is to utilize document.createEvent('CustomEvent')
and just the regular element.addEventListener()
. Anyway, implementing it the same way as onMonthChange
(a event-callback-mix, but it's working fine and allows a arbitrary number of handlers, too) would be a great solution, too. :smiley:
A event-based solution is even better than getters. I can't think of use cases which can't be implemented using a event-based solution and actually require getters. Tagging a new release would be great (possibly after switching to a event-based approach if you like)! :+1:
It looks like I have to change the dateRenderHandler
to onDateRender
... that is why it is beta I guess 😆
I like the custom events approach too, maybe in an other parallel universe, where IE is not a thing, there is a jsCalendar with custom events. So, for now I think we will play safe with my fake events (which now, in the beta, supports this
too).
PS: A version should have been released, but other things got in the way.
CustomEvent
works with IE9+ btw, but anyway, looking forward to it :+1: :smiley:
I don't know :thinking: ... Based on Mozilla's dec docs I think that IE9 supports the deprecated API. CustomEvents would make the code cleaner and the library faster.
I do like the CustomEvents idea and I think the best approach would be to implement the CustomEvents on a later release and provide a 2nd script (like a library extension) that would fix any incompatibility with older browsers.
But for now I should rush the 1.4.4 release, so I think we need to play safe.
Related commit 9b33654f2b1817065247ef2f2ae07481d106bc31
API was included in v1.4.4 Documentation needs be updated.
Great work, thanks @GramThanos :heart:
Sorry for the spam :P, I comment changes just to know what is going on later in case I forget them.