FullCalendar中的重复事件

Jun*_*aso 36 javascript jquery calendar fullcalendar fullcalendar-3

我正在使用jQuery FullCalendar作为我的网站中用于可用性议程的日历.

fullcalendar中是否有任何函数/方法/选项可以按天处理我的重复事件?例如,星期一只到上午7:00到9:00,周二 - 下午4:00到晚上9:00,这样的事情?

sli*_*oad 91

简单的重复事件

为了添加一个简单的替代方案,现在,Fullcalendar(有点)支持每周重复发生的事件.因此,如果您只需要:[Every Monday and Thursday from 10:00am to 02:00pm],您可以使用以下内容:

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
}],
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

这在Background事件中有记录,但它也适用于常规事件.

将其保存到数据库并不难.

添加一些限制

如果您不希望它们无限重复,则需要添加一些开始和结束日期.

所以,在DB中:

  • 让上面显示的事件代表父记录
  • 有另一个包含开始/结束日期的表.
  • 加入表示例:

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
Run Code Online (Sandbox Code Playgroud)

将此作为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"},]
}
Run Code Online (Sandbox Code Playgroud)

在客户端,使用fullcalendar的eventRender仅在其中一个时间范围内呈现事件.这样的事情应该有效:

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)
},
Run Code Online (Sandbox Code Playgroud)

假设您的活动结构如下:

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*/];
Run Code Online (Sandbox Code Playgroud)

的jsfiddle


过夜

如果你想要一夜之间重复的事件(比如这里),只需要24:00结束一段时间.例如:

{
  start: '10:00', //starts at 10 on monday
  end:   '27:00', //24+3 is handled correctly.
  dow: [1]
}
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

  • @Deepanshu只需添加另一个名为“ excludedDates”的表,这样您就可以获得每个range的例外列表。然后在“ eventRender”中,检查要渲染的事件不在该列表中。让我知道是否清楚。 (2认同)

Jua*_*les 13

看看这个网站...... http://fajitanachos.com/Fullcalendar-and-recurring-events/

它为重复发生的事件提供了很多好的东西.FullCalendar确实支持有关id的重复事件.您可以处理服务器端或客户端的事件,但首选项将是服务器端.我会给你一些想法,但不是全部.正如我所知,反复发生的事件是难以维持的.

如果你想在客户端处理它们,你将不得不循环重复事件的频率和几天的逻辑.您可能需要使用eventRender回调,然后使用选项回调渲染每个循环事件.这样做的问题是你仍然需要在数据库中为频率选项保存重复频率和逻辑运算符......

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

...然后,只要您编辑该事件,它就会编辑所有事件.如果你只需要删除一个事件,你会在你的逻辑中遇到一系列问题,很容易成为GIANT混乱.

第二个选择是做所有这个服务器端.创建两个表,一个包含父事件,第二个表包含所有重复.在父表中,您将存储常规信息,例如唯一ID,颜色,背景颜色,标题,allDay,isRecurring,频率,类型等.在子表中,您将使用父表中的唯一ID进行关联每次重复(请记住,如果要删除/编辑单个事件,子表行也需要具有自己的唯一ID,以及标记它所在表的列).当您添加定期事件时,您需要添加一个枚举字段,标记它是否是定期事件或不是AKA ...

柱:重复=枚举( '0', '1')---真/假

...然后你需要将每个重复添加到子表中,并使用其特定信息(如开始和结束等).当您查询事件时,您可以从父查询,然后如果事件是重复发生,则获取与之关联的事件第二个查询,或者您可以在一个查询中对table1.id = table2.parentID使用INNER JOIN.

正如您所看到的,重复发生的事件可以非常快速地得到非常详细的信息,找出您需要的逻辑,我希望这可以帮助您或至少开始的人.干杯.

  • 有关在服务器端实现重复事件的更多信息,请查看此链接,看起来第一个链接的作者使用此信息创建他的表:http://martinfowler.com/apsupp/recurring.pdf (3认同)

小智 6

这里不需要建立父子关系是为jquery中的重复事件提供简单解决方案的代码.完全日历在php文件中使用以下这些函数,您可以进一步调用所有事件.

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;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我使用了repeat_desk,其中我存储重复频率的json代码在此输入图像描述

和jquery来调用你的文件

 events:  {
                url: '<?php echo $lgc_plugindir; ?>includes/imagerotator.php',
                data: {
                    action: 'get_events'
                },
                type: 'POST'
            }
Run Code Online (Sandbox Code Playgroud)

我用它来wordpress你可以根据你的要求使用这个代码