Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API to access calendar columns #40

Open
PhrozenByte opened this issue Feb 27, 2019 · 9 comments
Open

API to access calendar columns #40

PhrozenByte opened this issue Feb 27, 2019 · 9 comments

Comments

@PhrozenByte
Copy link

PhrozenByte commented Feb 27, 2019

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! 👍

@GramThanos
Copy link
Owner

A few commits ago (d7fa9f7) 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.

@PhrozenByte
Copy link
Author

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! 👍

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. 😃

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)! 👍

@GramThanos
Copy link
Owner

GramThanos commented Feb 27, 2019

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.

@PhrozenByte
Copy link
Author

CustomEvent works with IE9+ btw, but anyway, looking forward to it 👍 😃

@GramThanos
Copy link
Owner

I don't know 🤔 ... 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.

@GramThanos
Copy link
Owner

Related commit 9b33654

@GramThanos
Copy link
Owner

API was included in v1.4.4
Documentation needs be updated.

@PhrozenByte
Copy link
Author

Great work, thanks @GramThanos ❤️

@GramThanos
Copy link
Owner

Sorry for the spam :P, I comment changes just to know what is going on later in case I forget them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants