Forum Documentation Showcase Pricing Learn more

[HOW-TO] Create a custom Calendar using repeating group


If you have two date objects (date1 and date2) that represent the start and end of an event, those define a date range (lets call it eventrange1). If you have a third date (let’s call it calendar_date), the following expression is true if calendar_date is within the event range:

eventrange1 contains point calendar_date

Date ranges are not a native JavaScript data type, they are specific to Bubble, but are conceptually used in other applications and libraries. In Bubble, a date range is constructed using the <- range -> operator like so:

date1 <- range -> date2

This returns an object of date range type. You can either construct date ranges and store them in your database as that type, or you can (USUALLY) construct them on-the-fly as above. So we could also write the first expression as:

date1 <- range -> date2 contains point calendar_date

If you add a Range field (of type date range) to your “Event” data type, you can do range-based constraints and comparisons like this:

Of course this implies that when you construct your Event objects, you (somewhere along the way) set their Range field. As an example:

If you don’t have ranges pre-constructed, you can’t do rangewise comparisons server-side (in a constraint). However, you can do them client side using the “Advanced” :filtered condition. Like this:

^^^ Keep in mind that this is all done client side, so what’s happening is all Events are being downloaded to the browser and then being iterated over by the :filter.


Hi @gf_wolfer! How did you go about making the calendar responsive? I have a nice calendar in place, with events showing and pretty much all features that the Full Calendar provides but I haven’t been able to make it responsive and not mess up the lay-out of the table.

Can you indeed post the steps?

Much obliged!


No problem, I’ll have to look back into what I did, will post something soon


Hi @gf_wolfer! Still interested to know what you did to make the calendar resposive :wink:


Wow, this is awesome! Thanks so much for posting! This has inspired me to try building a complimentary “by week” view version, (which I suspect is far less challenging than the month) but I seem to be stuck on the javascript bit. Here’s what I got…

  1. Create a repeating group of 7 columns (days) with 1 row
  2. Nest a vertical repeating group inside it that just has 1 column and 48 rows. (24hrs.*2=48 half-hour time slots).
  3. Javascript… crap.

Does anyone know if this is the best approach or if it can be done?



Mostly the Responsive part has to do with ensuring your elements, especially the Day of the week text elements will scale on a smaller screen. Hard to describe, but you can check out (or simply copy) the responsive calendar from this app :point_down:

Hope this helps!


Hi all, hi @codurly,

Thanks for the code - but it doesn’t seem to work for months where the first starts on a Sunday (like September 2019 and December 2019).

The first for loop that pushes the days onto the D array evaluates to empty on those days:

for(i=a.getDay()-2;0<=i;i–)D.push(new Date(t,e-1,n-i));

For September 2019 for instance (September 1st 2019).getDay = 0 therefore the loop doesn’t run in stead of running 6 times (as it should to add the August-days before the month starts (eg. 26,27,28,29,30 and 31).

The code does work for months starting on Monday through Saturday as for:

  • getDay = 1 (Monday): the loop doesn’t run - but the month starts on Monday so nothing needs to prepend the days.
  • getDay = 2 (Tuesday): the loop runs 1 time - which is correct
    . . .
  • getDay = 6 (Saturday): the loop runs 5 times - which is correct
    but for getDay = 0 (Sunday) the loop doesn’t run but needs to prepend 6 days!

my fix:
add an if-case for when getDay evaluates to 0.

Fixed code:

function getDaysInMonth(e,t) {
        var a=new Date(t,e,1),D=[],n=new Date(t,e,0).getDate(),b=a.getDay();
        if(b == 0) b=7;
	for(i=b-2;0<=i;i--)D.push(new Date(t,e-1,n-i));
	for(;a.getMonth()===e;)D.push(new Date(a)),a.setDate(a.getDate()+1);
	var g=new Date(t,e+1,1);
	for(i=D[D.length-1].getDay();6!=i;i++)D.push(new Date(g)),g.setDate(g.getDate()+1);
	for(i=D.length;42!=i;i++)D.push(new Date(g)),g.setDate(g.getDate()+1);
	return D;

Tried and tested :wink:


Hi @gf_wolfer,

Perfect! Thank you very much!