Recurring Events in FullCalendar Recurring Events in FullCalendar javascript javascript

Recurring Events in FullCalendar


Simple Repeating Events

To add a simple alternative to those listed here, Fullcalendar now (somewhat) supports weekly recurring events. So if you only need something like: [Every Monday and Thursday from 10:00am to 02:00pm], you can use the following:

events: [{    title:"My repeating event",    start: '10:00', // a start time (10am in this example)    end: '14:00', // an end time (2pm in this example)    dow: [ 1, 4 ] // Repeat monday and thursday}],

JSFiddle

This is documented in Background events but it works for regular events as well.

Saving this to a database wouldn't be hard.

Add some restrictions

If you don't want them to repeat infinitely, you would need to add some start and end dates.

So, in the DB:

  • Let the event shown above represent the parent record
  • Have another table with start/end dates.
  • Joined table example:

eventId  timeStart  timeEnd   dow    dateStart      dateEnd     1      10:00    12:00  [1,4]  2015/03/01   2015/04/01  // Month of March     1      10:00    12:00  [1,4]  2015/05/01   2015/06/01  // Month of May     1      10:00    12:00  [1,4]  2016/01/01   2017/01/01  // Year of 2017

Pass this to the client as JSON:

{ id:1, start:"10:00", end:"12:00", dow:[1,4],  ranges[{start:"2015/03/01", end:"2015/04/01"},         {start:"2015/05/01", end:"2015/06/01"},         {start:"2016/01/01", end:"2017/01/01"},]}

And client side, use fullcalendar's eventRender to only render events when there are within one of the time ranges. Something like this should work:

eventRender: function(event){    return (event.ranges.filter(function(range){ // test event against all the ranges        return (event.start.isBefore(range.end) &&                event.end.isAfter(range.start));    }).length)>0; //if it isn't in one of the ranges, don't render it (by returning false)},

That's assuming your events are structured as:

var repeatingEvents = [{    title:"My repeating event",    id: 1,    start: '10:00',     end: '14:00',     dow: [ 1, 4 ],     ranges: [{ //repeating events are only displayed if they are within at least one of the following ranges.        start: moment().startOf('week'), //next two weeks        end: moment().endOf('week').add(7,'d'),    },{        start: moment('2015-02-01','YYYY-MM-DD'), //all of february        end: moment('2015-02-01','YYYY-MM-DD').endOf('month'),    },/*...other ranges*/],},/*...other repeating events*/];

JSFiddle


Overnight

In case you want overnight repeating events (like here), just go over 24:00 for the end time. For instance:

{  start: '10:00', //starts at 10 on monday  end:   '27:00', //24+3 is handled correctly.  dow: [1]}

JSFiddle


Take a look at this site...http://fajitanachos.com/Fullcalendar-and-recurring-events/

It offers alot of good insite on recurring events. FullCalendar does support recurring events in respect to the id. You can handle the events either server side or client side, but the preference would be server side. I will give you some ideas, but its not all inclusive. As I have learned recurring events are a pain to maintain.

If you wanted to handle them client side, you would have to loop through the frequency of the repeating event and the logic of which days. You would probably need to use the eventRender callback, then render each looped event using the options callback. The problem with this will be that you still have to save the recurring frequency and a logical operator for your frequency option in your database...

(column1:frequency=(int)8, column2:type=enum(a'b'c), a=daily, b=weekly, c=monthly etc).

...and then anytime you edited that event it would edit all of the events. If you needed delete just one event you would run into a series of issues within your logic and it could easily become a GIANT mess.

The second option was to do all this server side. Creating two tables, one with the parent event, and the second with all its recurrences. In the parent table you would store the general information, such as a unique id, color, background color, title, allDay, isRecurring, frequency, type etc. In the child table, you would use the unique id from the parent table to associate each recurrence (keep in mind if you want to delete/edit individual events the child table rows need to have their own unique id as well and a column that labels which table it is located). When you add a recurring event, you need to add a enum field that labels whether or not it is a recurring event or not AKA...

column:recurring=enum('0','1')---true/false

... and then you need to add each recurrence, into the child table with its specific information like start and end etc. When you query the event you could either query from the parent and then if the event is recurring get those events associated in a second query, or you could use an INNER JOIN on table1.id=table2.parentID in one single query.

As you can see, recurring event can get very detailed very fast, find out what logic you need and I hope this helps you or someone at least get started. Cheers.


No need to make parent and child relationship here is the code that provide simple solution for recurring events in jquery Full calender use these below functions in your php file that you use further to call all your events.

function render_fccalendar_events() {        $_POST['start'] = strtotime('2013-05-01');        $_POST['end'] = strtotime('2013-05-31');        $start = date('Y-m-d',$_POST['start']);        $end = date('Y-m-d', $_POST['end']);        $readonly = (isset($_POST['readonly'])) ? true : false;            $events = fcdb_query_events($start, $end);               render_json(process_events($events, $start, $end, $readonly));}function process_events($events, $start, $end, $readonly) {    if ($events) {        $output = array();        foreach ($events as $event) {            $event->view_start = $start;            $event->view_end = $end;            $event = process_event($event, $readonly, true);            if (is_array($event)) {                foreach ($event as $repeat) {                    array_push($output, $repeat);                }            } else {                array_push($output, $event);            }        }        return $output;    }}function process_event($input, $readonly = false, $queue = false) {    $output = array();    if ($repeats = generate_repeating_event($input)) {        foreach ($repeats as $repeat) {            array_push($output, generate_event($repeat));        }    } else {        array_push($output, generate_event($input));    }    if ($queue) {        return $output;    }    render_json($output);}function generate_event($input) {    $output = array(        'id' => $input->id,        'title' => $input->name,        'start' => $input->start_date,        'end' => $input->end_date,        'allDay' => ($input->allDay) ? true : false,        //'className' => "cat{$repeats}",        'editable' => true,        'repeat_i' => $input->repeat_int,        'repeat_f' => $input->repeat_freq,        'repeat_e' => $input->repeat_end    );    return $output;}function generate_repeating_event($event) {    $repeat_desk = json_decode($event->repeat_desk);    if ($event->repeat == "daily") {        $event->repeat_int =0;        $event->repeat_freq = $repeat_desk->every_day;    }    if ($event->repeat == "monthly") {        $event->repeat_int =2;                $event->repeat_freq = $repeat_desk->every_month;    }    if ($event->repeat == "weekly") {        $event->repeat_int =1;                       $event->repeat_freq = $repeat_desk->every_weak;    }    if ($event->repeat == "year") {        $event->repeat_int =3;                                $event->repeat_freq = $repeat_desk->every_year;    }    if ($event->occurrence == "after-no-of-occurrences") {        if($event->repeat_int == 0){            $ext = "days";        }        if($event->repeat_int == 1){            $ext = "weeks";        }        if($event->repeat_int == 2){            $ext = "months";        }        if($event->repeat_int == 3){            $ext = "years";        }       $event->repeat_end =  date('Y-m-d',strtotime("+" . $event->repeat_int . " ".$ext));    } else if ($event->occurrence == "no-end-date") {        $event->repeat_end = "2023-04-13";    } else if ($event->occurrence == "end-by-end-date") {        $event->repeat_end = $event->end_date;    }    if ($event->repeat_freq) {        $event_start = strtotime($event->start_date);        $event_end = strtotime($event->end_date);        $repeat_end = strtotime($event->repeat_end) + 86400;        $view_start = strtotime($event->view_start);        $view_end = strtotime($event->view_end);        $repeats = array();        while ($event_start < $repeat_end) {            if ($event_start >= $view_start && $event_start <= $view_end) {                $event = clone $event; // clone event details and override dates                $event->start_date = date(AEC_DB_DATETIME_FORMAT, $event_start);                $event->end_date = date(AEC_DB_DATETIME_FORMAT, $event_end);                array_push($repeats, $event);            }            $event_start = get_next_date($event_start, $event->repeat_freq, $event->repeat_int);            $event_end = get_next_date($event_end, $event->repeat_freq, $event->repeat_int);        }        return $repeats;    }    return false; }function get_next_date($date, $freq, $int) {    if ($int == 0)        return strtotime("+" . $freq . " days", $date);    if ($int == 1)        return strtotime("+" . $freq . " weeks", $date);    if ($int == 2)        return get_next_month($date, $freq);    if ($int == 3)        return get_next_year($date, $freq);}function get_next_month($date, $n = 1) {    $newDate = strtotime("+{$n} months", $date);    // adjustment for events that repeat on the 29th, 30th and 31st of a month    if (date('j', $date) !== (date('j', $newDate))) {        $newDate = strtotime("+" . $n + 1 . " months", $date);    }    return $newDate;}function get_next_year($date, $n = 1) {    $newDate = strtotime("+{$n} years", $date);    // adjustment for events that repeat on february 29th    if (date('j', $date) !== (date('j', $newDate))) {        $newDate = strtotime("+" . $n + 3 . " years", $date);    }    return $newDate;}function render_json($output) {    header("Content-Type: application/json");    echo json_encode(cleanse_output($output));    exit;}function cleanse_output($output) {    if (is_array($output)) {        array_walk_recursive($output, create_function('&$val', '$val = trim(stripslashes($val));'));    } else {        $output = stripslashes($output);    }    return $output;}function fcdb_query_events($start, $end) {    global $wpdb;    $limit = ($limit) ? " LIMIT {$limit}" : "";    $result = $wpdb->get_results("SELECT id, name,start_date,end_date,repeat_desk,`repeat`,occurrence,occurrence_desk                                        FROM " . $wpdb->prefix . "lgc_events                                        WHERE (                                        (start_date >= '{$start}' AND start_date < '{$end}')                                        OR (end_date >= '{$start}' AND end_date < '{$end}')                                        OR (start_date <= '{$start}' AND end_date >= '{$end}')                                        OR (start_date < '{$end}' AND (`repeat`!= ''))                            )                                        ORDER BY start_date{$limit};");    return return_result($result);}function return_result($result) {    if ($result === false) {        global $wpdb;        $this->log($wpdb->print_error());        return false;    }    return $result;}

in the above code i used repeat_desk in which i store json code for repeat frequencyenter image description here

and jquery to call your file

 events:  {                url: '<?php echo $lgc_plugindir; ?>includes/imagerotator.php',                data: {                    action: 'get_events'                },                type: 'POST'            }

i used this for wordpress you can use this code as per your requirement