-1

I am trying to make a version of fullcalendar that will load from a database and allow recurring events. This is my code.

<script>
$(document).ready(function() {
$.ajax({
    url: 'process.php',
    type: 'POST',
    data: 'type=fetch',
    async: false,
    success: function(s){
        json_events = s;
    }
});
$('#calendar').fullCalendar({
    events: JSON.parse(json_events),
    header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
    },
    defaultView: 'month',
    editable: true, 
    slotDuration: '00:30:00',
    eventRender: function(event){
        return (event.ranges.filter(function(range){ 
            return (event.start.isBefore(range.dowend) && event.end.isAfter(range.dowstart));
        }).length) > 0;
    }, 
    eventReceive: function(event){
        var title = event.title;
        var start = event.start.format("YYYY-MM-DD[T]HH:mm:SS");
        $.ajax({
            url: 'process.php',
            data: 'type=new&title='+title+'&startdate='+start+'&zone='+zone,
            type: 'POST',
            dataType: 'json',
            success: function(response){
                event.id = response.eventid;
                $('#calendar').fullCalendar('updateEvent',event);
            },
            error: function(e){
                console.log(e.responseText);
            }
        });      
    }
});
});
</script>

This is process.php

    <?php
include('config.php');
    {
    $events = array();
    $query = mysqli_query($con, "SELECT * FROM revent");
    while($fetch = mysqli_fetch_array($query,MYSQLI_ASSOC))
    {
    $e = array();
    $e['id'] = $fetch['id'];    
    $e['start'] = $fetch['start'];
    $e['end'] = $fetch['end'];
    $e['title'] = $fetch['title'];
    $e['dow'] = $fetch['dow'];
    $e['ranges'] = [ array("dowstart" => $fetch['dowstart'],"dowend" => $fetch['dowend'])];
    $e['color'] = $fetch['color'];
    array_push($events, $e);
    }
    echo json_encode($events);
};
?>

This is the relevant table

This is the json created by process.php

[
  {"id":"1","start":"10:00","end":"12:00","title":"my event1","dow":"2","ranges":[{"dowstart":"2018-06-07","dowend":"2018-06-27"}],"color":"lightgreen"},
  {"id":"2","start":"14:00","end":"18:00","title":"my event2","dow":"0,5","ranges":[{"dowstart":"2018-06-07","dowend":"2018-07-07"}],"color":"lightblue"},
  {"id":"4","start":"14:00","end":"16:00","title":"my event3","dow":"1,4","ranges":[{"dowstart":"2018-06-07","dowend":"2018-07-07"}],"color":"pink"},
  {"id":"5","start":"14:00","end":"16:00","title":"my event4","dow":"1,4","ranges":[{"dowstart":"2018-08-08","dowend":"2018-08-18"}],"color":"pink"}
] 

This is working now! It needed this line $e['ranges'] = [ array("dowstart" => $fetch['dowstart'],"dowend" => $fetch['dowend'])]; and I changed ranges to range in eventRender.

lebleg
  • 1
  • 4
  • Please **do not** use `async: false` - it is deprecated due to the fact it creates terrible user experience by locking up the browser. You can expect in future it will stop working entirely. You can get round this in several ways in your case - either by declaring your calendar inside (or from a function called from inside) your ajax "success", or by declaring your event source in the fullCalendar recommended way: https://fullcalendar.io/docs/events-function (in this way fullCalendar can also fetch extra events dynamically as the view changes, if need be) – ADyson Aug 06 '18 at 14:10
  • Anyway, where did you get the "ranges" idea from? It originated here, which as you can see, shows you need a little bit of extra code to make it work...it's not a standard part of fullCalendar. https://stackoverflow.com/questions/15161654/recurring-events-in-fullcalendar . P.S. This gets asked about once a week on the fullCalendar tag, bizarrely no-one seems to be capable of researching it properly - yet it's only a google search away. – ADyson Aug 06 '18 at 14:12
  • ADyson. I don't believe any of the questions match my problem. What is async: false? – lebleg Aug 06 '18 at 14:20
  • `async: false`? Right here you used it, in your code: `$.ajax({ url: 'process.php', type: 'POST', data: 'type=fetch', async: false,`. It stops the AJAX request from working asynchronously, as it's designed to. As a result it runs single-threaded and causes the browser to freeze for the duration of the request, the user cannot click on anything in the page. If the request goes on for a few seconds, or longer than expected for some reason, then the user can think the browser has crashed – ADyson Aug 06 '18 at 14:21
  • The link I showed you will explain about the `ranges` functionality. You used `dowstart` instead of `start` within the range object but otherwise it appears to be an identical concept. Like I asked, where did you get the idea for it? The original idea appeared on that question first. – ADyson Aug 06 '18 at 14:22
  • Ok looking at your PHP a bit more closely I think `$e['ranges']['dowstart']` is not right. This will make a property called "dowstart" directly within `ranges`. So ranges will be a single object with a property, not an array. Check the JSON you're generating, you can see it. Ranges needs to be an array, containing 1 or more objects which each contains a dowstart and dowend object. The reason is fails when you uncomment eventRender is that the data is not in a structure the code is expecting...probably you have a console error which mentions it. ".filter()" expects an array, not an object. – ADyson Aug 06 '18 at 15:51
  • \I have posted the JSON in the question. Am I not right in thinking that the ranges are being sent with an array containing e.g. "dowstart":"2018-06-07","dowend":"2018-06-27" – lebleg Aug 06 '18 at 16:57
  • I got the idea from here https://stackoverflow.com/questions/35672504/repeating-time-on-fullcalendar-event – lebleg Aug 06 '18 at 18:00
  • Yes, I know, like I said, you can check your JSON yourself as well and see that ranges is an object. Objects have `{` and `}` round them, arrays have `[` and `]`. That's basic JSON / JavaScript syntax. The code in that example you linked to also creates ranges as an array, not an object. – ADyson Aug 06 '18 at 18:32
  • if you want to fix that in PHP and just include a single range, then `$e['ranges'] = ['dowstart'] = array( array("dowstart" => $fetch['dowstart'], "dowend" => $fetch['dowend']))` I think (untested) – ADyson Aug 06 '18 at 18:35
  • I have made a change in process.php which is giving an array which looks right to me but I still get the blank calendar when I uncomment eventRender ??? – lebleg Aug 07 '18 at 09:27
  • do you ever check your browser's console for errors and try to debug them, instead of just complaining about a blank screen?? Do you understand how to do that? You'd probably make a lot more progress if you did. http://jsfiddle.net/qxLuLhsf/86/ - check the console there, you'll see "Uncaught ReferenceError: ranges is not defined". I believe it's because of `isBefore(ranges.dowend)` and `isAfter(ranges.dowstart)` - there's no such variable as just "ranges". I would think it needs to be `range` in each case, since that's the input variable to the callback – ADyson Aug 07 '18 at 09:57
  • I do look at the console. Thank you very much for your help, that has done it. – lebleg Aug 07 '18 at 10:27
  • If you did, you'd have spotted that error, but you didn't mention it, or apparently do anything about it, you just complained about a blank calendar with no further detail. Therefore, I assumed you mustn't have been looking in the console. Anyway, I'm glad this has resolved your issue. if you feel I have helped you, please mark the answer below as "accepted" (click the tick icon next to the answer so it turns green) - cheers. – ADyson Aug 07 '18 at 10:33

1 Answers1

0

There are a few little errors in your original code:

1) The PHP for creating the "ranges" array is wrong and will produce a single object instead of the array which the JavaScript is expecting.

Your code produces an object:

"ranges":{"dowstart":"2018-06-07","dowend":"2018-06-27"}

when you need an array containing (one or more) objects:

"ranges":[{"dowstart":"2018-06-07","dowend":"2018-06-27"}]

The PHP needs to be like this to produce the correct JSON:

$e['ranges'] = [ array("dowstart" => $fetch['dowstart'],"dowend" => $fetch['dowend'])];

2) Somehow in copying the "eventRender" JavaScript code from the original source you introduced a typo, which is causing a JavaScript error about an undefined variable:

isBefore(ranges.dowend) and isAfter(ranges.dowstart)

should be

isBefore(range.dowend) and isAfter(range.dowstart) respectively, since range is the range variable passed into the "filter" callback.

Once you correct those two things, it will work correctly. Working demo using your sample data: http://jsfiddle.net/qxLuLhsf/98/

ADyson
  • 57,178
  • 14
  • 51
  • 63