Creating Calendar with Variable Length Appointments

Hello everyone and thanks for your help in advance. I am a back-end developer and relative novice on HTML and CSS. I am developing an online calendar that consumes JSON data from a webservice. I now need to work on formatting the data and need advice on exactly how to do that. I now there are components that can be integrated such as DayPilot with the article referring to it at : http://www.codeproject.com/Articles/404647/AJAX-Event-Calendar-Scheduler-for-ASP-NET-MVC-in, but I really need more granular control over the project and don’t think the component is the best option. One of the biggest problems I am having is when an appointment spans multiple timeslots or if it spans an incremental amount of time, for example 15 minute slots with a 10 minute appointment. Or multiple appointments overlapping each other, for example, on the article I referenced, the first graphic shows Event 17 overlapping Event 8. Would someone be able to walk me through the basics of how to accomplish this? I assume its a combination of CSS and javascript, but am too much of a front-end novice to figure it out. Thanks for the help.

OK, just thinking out-loud about the theory, rather than offering a working solution at this point.
To start the calendar looks like a html table, simple enough.
For the actual event blocks, I’m thinking absolutely positioned divs in the table cells with visible overflow. I have not tried anything like that yet, so not sure if it will work.
The block heights will of course be defined by css, but the data come from your scripting.
So would need dynamically created css.
I’m not an advocate of in-line css, but this may be a case for it, or maybe have the css echoed out in the page head.

<style>
.event1{height:4em}
.event2{height:7em} /* Etc... */
</style>

Exactly how depends on the nature of the scripting you are using to get the data. So if it were PHP from SQL you may have a while or foreach in the style tags to do that.

Thanks for the response. Like I said earlier, the data is a call from a SQL server that returns JSON with a beginning date, ending date, and event name to get started. So I guess I could return a calculated length of appointment and then set the size of the event based on that (or I guess I could even create it server side). But if I use absolute positioning, won’t that be prone to breaking depending on viewport size? Again, I’m so inexperienced on client side, I really don’t know.

Yes, both tables and abs pos can be difficult in RWD. But these were just initial thoughts based on those images in the link. You would need to decide how it would look on the small screen too.

This is a quick crude example of the html/css.
It’s not responsive yet. That will actually be tricky. Normally with tables I turn rows into stacked columns. But here the events overflow across rows down the column, so that won’t work.

<!DOCTYPE html>
<html>
    <head>
        <title>Titile</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name=viewport content="width=device-width, initial-scale=1">
        <style>
            /* This part would be in a static external css */
            td {
                outline: dashed 1px #aaa;
                position: relative;
                overflow: visible;
                min-width: 5em;
                }
            .evt {
                position: absolute;
                width: 5em;
                top: 0;
                background: #faa;
                outline: solid 1px #f00;
            }
            /* This part would be churned out here dynamically from your data */
            .event1 {height: 6em;}
            .event2 {height: 2em;}
            .event3 {height: 5em;}
            .event4 {height: 3em;}
        </style>
    </head>
    <body>
        <h1>The Title</h1>
        <table>
            <tr>
                <th></th><th>Date</th><th>Date</th><th>Date</th><th>Date</th>
            </tr>
            <tr>
                <th>Time</th><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Time</th><td><div class="evt event1">Event 1</div></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Time</th><td></td><td><div class="evt event2">Event 2</div></td><td></td><td></td>
            </tr>
            <tr>
                <th>Time</th><td></td><td></td><td><div class="evt event3">Event 3</div></td><td></td>
            </tr>
            <tr>
                <th>Time</th><td></td><td></td><td></td><td><div class="evt event4">Event 4</div></td>
            </tr>
            <tr>
                <th>Time</th><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Time</th><td></td><td></td><td></td><td></td>
            </tr>
        </table>
    </body>
</html>

I have a cunning plan.
I have it part way working, but it needs some polishing.

I’m running out of time this evening, so here it the unfinished idea.
As I say, the concept is there but it needs polishing.
The idea is I invert the table structure, rows become columns and columns become rows. That way the table can be collapsed into column groups, rather than by rows.
It really just needs the widths sorting out and better presentation, so there is enough for someone to take the idea further.

<!DOCTYPE html>
<html>
    <head>
        <title>Titile</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name=viewport content="width=device-width, initial-scale=1">
        <style>
            /* This part would be in a static external css*/
            table.invert {
                display: block;
            }
            .invert tr {
                display: inline-block;
            }
            .invert th,
            .invert td {
                display: block;
                outline: dashed 1px #aaa;
                position: relative;
                overflow: visible;
                min-width: 5em;
                min-height: 1.5em;
            }
            @media screen and (max-width: 48em) {
                .invert tr {
                    display: block;
                }
                .invert .head { display: none }
            }
            .evt {
                position: absolute;
                width: 5em;
                top: 0;
                background: #faa;
                outline: solid 1px #f00;
            }
            
            /* This part would be churned out here dynamically from your data */
            .event1 {height: 6em;}
            .event2 {height: 2em;}
            .event3 {height: 5em;}
            .event4 {height: 3em;}
        </style>
    </head>
    <body>
        <h1>The Title</h1>
        <table class="invert">
            <tr class="head">
                <th></th><th>Time</th><th>Time</th><th>Time</th><th>Time</th><th>Time</th><th>Time</th>
            </tr>
            <tr>
                <th>Date</th><td></td><td></td><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td><div class="evt event1">Event 1</div></td><td></td><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td></td><td><div class="evt event2">Event 2</div></td><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td></td><td></td><td><div class="evt event3">Event 3</div></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td></td><td></td><td></td><td><div class="evt event4">Event 4</div></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td></td><td></td><td></td><td></td><td></td><td></td>
            </tr>
            <tr>
                <th>Date</th><td></td><td></td><td></td><td></td><td></td><td></td>
            </tr>
        </table>
    </body>
</html>

Here is a further example to look at.

Though it will get more complex with a number of events in one day. You would need to introduce width controls to the event blocks, but it’s a start.

First of all, thank you for your effort and help. But I’m such a newbie, I’m trying to figure out what is happening with the stylesheet.

It is fairly unorthodox. I broke up the usual display properties of the table to make rows and columns swap places.
So rows are vertical and columns are horizontal.
Because row are grouped in a common parent, they can be stacked, but columns can’t, hence the swap.

Thank you for your efforts. But I’m not following the reasoning why you would want to do this. Thanks for your patience. I’m a newbie trying to turn ninja.

It sounded like you need this to be responsive, which is a reasonable requirement.
This is a method of making the table responsive, by allowing it to collapse into a single column.
Collapsing a table is something I have done before (credit to @PaulOB for showing me how).
But this was a bit more of a challenge, because the event boxes span a number of rows, I can’t break those rows up in the usual way. The column have to stay in a group, so I make the columns be rows, but then still dis play like column (vertical), which required a bit of css magic.

Yes, you are correct. Thank you so much for your help.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.