Fullcalendar - Uncaught TypeError: Cannot read property 'hasTime' of undefined
использую Fullcalendar v2.6.0 в связке с php + sqlite PDO для хранения событий в локальной БД. У меня возникла ошибка:
fullcalendar.js:10416 Uncaught TypeError: Cannot read property 'hasTime' of undefined
at normalizeEventTimes (calendar.js:10416)
at normalizeEventDates (fullcalendar.js:10385)
at assignDatesToEvent (fullcalendar.js:10376)
at buildEventFromInput (fullcalendar.js:10363)
at Calendar_constructor.renderEvent (fullcalendar.js:10205)
at HTMLDivElement.<anonymous> (fullcalendar.js:40)
at Function.each (jquery.min.js:2)
at n.fn.init.each (jquery.min.js:2)
at n.fn.init.$.fn.fullCalendar (fullcalendar.js:32)
at Object.success (Calendar.php:269) - см. ниже комментарий в коде.
У меня есть модальное окно, куда пользователь вводит title, start, end и эти данные отправляются туда.
events: "ajax.php",
dayClick: function(date,jsEvent,view){
var clickDate = date.format('YYYY-MM-DD');
console.log(clickDate);
form.dialog({
modal: true,
width: '30%',
title: "Добавление события",
buttons: [{
id: 'add',
text: 'Добавить',
click: function() {
$.ajax({
type: "POST",
url: "ajax.php",
data: {
title: event_title.val(),
start: event_start.val(),
end: event_end.val()
}
// **здесь начинает ругаться**
success: function(){
Calendar.fullCalendar('renderEvent', {
title: event_title.val(),
start: event_start.val(),
end: event_end.val(),
allDay: false
});
}
});
emptyForm();
}
}
}
Я принимаю из БД такой формат:
{"id":"1","title":"sdsd","start":"2022-03-29","end":"2022-03-29"}
Мой ajax.php
<?php
$bdd = new PDO('sqlite:Calendar.db');
$bdd->exec("CREATE TABLE if not exists events (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, start TEXT, end TEXT)");
if(isset( $_POST['title'], $_POST['start'], $_POST['end']))
{
$title = $_POST['title'];
$start = $_POST['start'];
$end = $_POST['end'];
$sql = "INSERT INTO events (title, start, end) VALUES (:title, :start, :end)";
$q = $bdd->prepare($sql);
$q->execute(array(':title'=>$title, ':start'=>$start, ':end'=>$end));
$json = array();
$requete = "SELECT * FROM events";
$resultat = $bdd->query($requete) or die(print_r($bdd->errorInfo()));
echo json_encode($resultat->fetch(PDO::FETCH_ASSOC));
}
?>
Я джун и не пойму в чем проблема, по всей видимости я накосячил с датой/временем и несколько дней не могу найти решение. Помогите разобрать ошибку и привести рабочий пример.
var Calendar = jQuery('#calendar');
var Months = jQuery('#months');
var event_title = jQuery('#event_title');
var event_start = jQuery('#event_start');
var event_end = jQuery('#event_end');
var event_description = jQuery('#description');
var form = jQuery('#dialog-form');
Calendar.fullCalendar({
aspectRatio: 1.5,
fixedWeekCount: false,
showNonCurrentDates: false,
eventLimit: true,
header: {
left: "",
center: "title",
right: "prev today next"
},
events: "ajax.php",
//клик по дню
dayClick: function(date,jsEvent,view){
var clickDate = date.format('YYYY-MM-DD');
console.log(clickDate);
form.dialog({
modal: true,
width: '30%',
title: "Добавление события",
buttons: [{
id: 'add',
text: 'Добавить',
click: function() {
$.ajax({
type: "POST",
url: "ajax.php",
data: {
title: event_title.val(),
start: event_start.val(),
end: event_end.val()
}
//начало проблемы
success: function(){
Calendar.fullCalendar('renderEvent', {
title: event_title.val(),
start: event_start.val(),
end: event_end.val(),
allDay: false
});
}
});
emptyForm();
}
},
{ id: 'edit',
text: 'Изменить',
click: function() {
}
},
{ id: 'cancel',
text: 'Отмена',
click: function() {
$(this).dialog('close');
emptyForm();
}
},
{ id: 'delete',
text: 'Удалить',
click: function() {
},
disabled: true
}]
});
//календарь для выбора начала и конца события в модалке
event_start.val(clickDate);
event_end.val(clickDate);
$('.datepicker').datepicker({ dateFormat: 'yy-mm-dd' });
formOpen('add');
},
//клик по событию
eventClick: function (event, jsEvent, view) {
$("#eventInfo").html(event.description);
$("#eventContent").dialog({
modal: true,
width: '30%',
title: event.title,
closeText: "",
buttons: [{text: "Закрыть",
click: function() { $(this).dialog("close")}}]
});
},
// Выпадающий список с месяцами
eventAfterAllRender: function(){
var date = Calendar.fullCalendar('getDate');
var month = date.month();
month ++;
Months.val(month);
var $header = Calendar.find('.fc-left');
if (!(Calendar.find("#months").length > 0)) {
$header.prepend(Months);}
}
});
Months.off('change').change(function(){
var $select = jQuery(this);
var newMonth = parseInt($select.val());
newMonth--;
var date = Calendar.fullCalendar('getDate');
date.month(newMonth);
Calendar.fullCalendar('gotoDate', date);
});
// функция очистки модалки
function emptyForm() {
event_title.val("");
event_start.val("");
event_end.val("");
<!-- event_description.val(""); -->
}
//режимы открытия модалки
function formOpen(mode) {
if(mode == 'add') {
$('#add').show();
$('#edit').hide();
$("#delete").button("option", "disabled", true);
}
else if(mode == 'edit') {
$('#edit').show();
$('#add').hide();
$("#delete").button("option", "disabled", false);
}
form.dialog('open');
}
> css
body{
background: #f7f7f7 !important;
}
.menu-event{
float: right;
padding: 10px;
flex-basis: 290px;
word-wrap: break-word;
border-radius: 10px;
background: white;
display: inline-block;
flex: 1 1 50px;
width: 20%;
margin-right: 35px;
height: 710px;
}
.box {
border-radius:10px;
flex-wrap: wrap;
justify-content: space-around;
width:70%;
display: inline-block;
position:relative;
}
.calendar{
border-radius:10px;
padding: 7px;
background: white;
display: inline-block;
flex: 1 1 50px;
width: 100%;
}
.month{
font-size: 12px;
padding:10px;
border:1px solid #ddd;
border-radius:10px;
}
.month:hover{
cursor: pointer;}
a{text-decoration: underline;}
.fc-day-grid-event > .fc-content{
white-space: overflow;
text-overflow: ellipsis;
font-size:10px;
max-height:45px;
padding:1px;
}
select{text-align-last: center;}
th.fc-sat, th.fc-sun, td.fc-sat, td.fc-sun{ color:red;}
.fc-basic-view td.fc-day-number{padding:1px 5px 0 0;}
td.fc-today {color:white;}
.fc-day.fc-today {
position: relative;
right: 1px;
top:0px;
}
.fc-today{
background: rgba(255,220,40,.15);
}
.fc-day.fc-today::before,
.fc-day.fc-today::after {
content: '';
position: absolute;
top: 0;
right: 0;
border-color: transparent;
border-style: solid;
}
.fc-day.fc-today::before {
width:20px;
height:11px;
}
.fc-day.fc-today::after {
border-radius: 50% 0 0 50%;
width:20px;
height:11px;
background-color: #E30611;
}
.fc-content:hover {
background-color: rgba(185, 233, 255, 1);
cursor: pointer;
position: relative;
white-space: normal;
}
.fc-head{
background: #F0F8FF;
}
div.fc-more-popover > .fc-widget-content > .fc-event-container >.fc-day-grid-event > .fc-content{
white-space: normal;
}
.fc-ltr .fc-basic-view .fc-day-number {
background: rgba(240, 248, 255, 0.4);
}
.fc td{
border: 2px solid #DCDCDC;
}
.btn{
font-size: 16px;
padding:10px;
border:1px solid #ddd;
border-radius:10px;
background: white;
}
> html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Календарь событий</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.0/fullcalendar.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.0/fullcalendar.min.css"rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
</head>
<body>
<div class="box">
<select class="month" id="months" tabindex="0">
<option selected disabled>Выбрать месяц</option>
<option value="1">Январь</option>
<option value="2">Февраль</option>
<option value="3">Март</option>
<option value="4">Апрель</option>
<option value="5">Май</option>
<option value="6">Июнь</option>
<option value="7">Июль</option>
<option value="8">Август</option>
<option value="9">Сентябрь</option>
<option value="10">Октябрь</option>
<option value="11">Ноябрь</option>
<option value="12">Декабрь</option>
</select>
<div id="calendar" class="calendar"></div>
<div id="eventContent">
<div id="eventInfo">
</div>
</div>
</div>
<div id="dialog-form" style="display:none" title="Событие">
<form>
<p><label for="event_title">Заголовок события</label>
<input type="text" id="event_title" value=""></p>
<p><label for="event_start">Начало</label>
<input type="text" value="" class="datepicker" id="event_start"/></p>
<p><label for="event_end">Конец</label>
<input type="text" value="" class="datepicker" id="event_end"/></p>
</form>
</div>
</body>
</html>