I'm editing fullcalendar to adapt it to my needs. First of all here is the code:
<!----HTML---->
<link href='assets/css/fullcalendar.css' rel='stylesheet' />
<link href='assets/css/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='assets/js/moment.min.js'></script>
<script src='assets/js/jquery-ui.min.js'></script>
<script src='assets/js/fullcalendar_not_min.js'></script>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Scegli Zona di Servizio</h4>
</div>
<div class="modal-body" id="myModalBody">
<div class="form-group">
<label for="sel1">Select list (select one):</label>
<select class="form-control" id="mySelect">
<?php
foreach($zone_servizio_array as $zona){
echo '<option value="'.$zona->getId().'">'.$zona->getNome().'</option>';
}
?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="save();" data-dismiss="modal">Save changes</button>
</div>
</div>
</div>
</div>
<body>
<div id='wrap'>
<div id='external-events'>
<h4>Agenti</h4>
<?php
foreach ($agenti_array as $agente){
echo '<div class=\'fc-event\'>'.$agente->getNome().' '.$agente->getCognome().'</div>';
}
?>
<p>
<img src="assets/img/trashcan.png" id="trash" alt="">
</p>
</div>
<div id='calendar_buttons' align="left">
<div class="btn-group" role="group" aria-label="..." >
<button type="button" class="btn btn-success"><span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span> Salva</button>
<button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Ripristina</button>
</div>
</div>
<div id='calendar'></div>
<div style='clear:both'></div>
<xspan class="tt">x</xspan>
</div>
</body>
Here is the Javascript:
<script>
var salva = 0; //control variable
function save(){//to change the control variable value
salva = 1;
}
function saveEvent(event, title, start, zone){
$('#myModal').modal('show');
$('#myModal').on('hidden.bs.modal', function (e) {
zona_servizio = document.getElementById('mySelect').value;
if(salva == 1){
console.log('before save event', event, title, start, zone);
$.ajax({
url: 'process.php',
data: 'type=new&title='+title+'&startdate='+start+'&zone='+zone+'&zona_servizio='+zona_servizio,
type: 'POST',
dataType: 'json',
success: function(response){
event.id = response.eventid;
$('#calendar').fullCalendar('updateEvent',event);
},
error: function(e){
console.log(e.responseText);
}
});
}else{
$('#calendar').fullCalendar('removeEvents');
getFreshEvents();
}
});
//$('#calendar').fullCalendar('updateEvent',event);
salva = 0;
console.log('end save event', event);
}
$(document).ready(function() {
zone = "01:00"; //Change this to your timezone
$.ajax({
url: 'process.php',
type: 'POST', // Send post data
data: 'type=fetch',
async: false,
success: function(s){
json_events = s;
}
});
var currentMousePos = {
x: -1,
y: -1
};
jQuery(document).on("mousemove", function (event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function() {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
$('#calendar').fullCalendar({
events: JSON.parse(json_events),
//events: [{"id":"14","title":"New Event","start":"2015-01-24T16:00:00+04:00","allDay":false}],
utc: true,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
droppable: true,
slotDuration: '00:30:00',
**eventReceive**: function(event){
var title = event.title;
var start = event.start.format("YYYY-MM-DD[T]HH:mm:SS");
console.log('event Receive', event, title, start, zone);
saveEvent(event, title, start, zone);
},
eventDrop: function(event, delta, revertFunc) {
var title = event.title;
var start = event.start.format();
var end = (event.end == null) ? start : event.end.format();
$.ajax({
url: 'process.php',
data: 'type=resetdate&title='+title+'&start='+start+'&end='+end+'&eventid='+event.id,
type: 'POST',
dataType: 'json',
success: function(response){
if(response.status != 'success')
revertFunc();
},
error: function(e){
revertFunc();
alert('Error processing your request: '+e.responseText);
}
});
},
eventClick: function(event, jsEvent, view) {
console.log(event.id);
var title = prompt('Event Title:', event.title, { buttons: { Ok: true, Cancel: false} });
if (title){
event.title = title;
console.log('type=changetitle&title='+title+'&eventid='+event.id);
$.ajax({
url: 'process.php',
data: 'type=changetitle&title='+title+'&eventid='+event.id,
type: 'POST',
dataType: 'json',
success: function(response){
if(response.status == 'success')
$('#calendar').fullCalendar('updateEvent',event);
},
error: function(e){
alert('Error processing your request: '+e.responseText);
}
});
}
},
eventResize: function(event, delta, revertFunc) {
console.log(event);
var title = event.title;
var end = event.end.format();
var start = event.start.format();
$.ajax({
url: 'process.php',
data: 'type=resetdate&title='+title+'&start='+start+'&end='+end+'&eventid='+event.id,
type: 'POST',
dataType: 'json',
success: function(response){
if(response.status != 'success')
revertFunc();
},
error: function(e){
revertFunc();
alert('Error processing your request: '+e.responseText);
}
});
},
eventDragStop: function (event, jsEvent, ui, view) {
if (isElemOverDiv()) {
var con = confirm('Are you sure to delete this event permanently?');
if(con == true) {
$.ajax({
url: 'process.php',
data: 'type=remove&eventid='+event.id,
type: 'POST',
dataType: 'json',
success: function(response){
console.log(response);
if(response.status == 'success'){
$('#calendar').fullCalendar('removeEvents');
getFreshEvents();
}
},
error: function(e){
alert('Error processing your request: '+e.responseText);
}
});
}
}
}
});
function getFreshEvents(){
$.ajax({
url: 'process.php',
type: 'POST', // Send post data
data: 'type=fetch',
async: false,
success: function(s){
freshevents = s;
}
});
$('#calendar').fullCalendar('addEventSource', JSON.parse(freshevents));
}
function isElemOverDiv() {
var trashEl = jQuery('#trash');
var ofs = trashEl.offset();
var x1 = ofs.left;
var x2 = ofs.left + trashEl.outerWidth(true);
var y1 = ofs.top;
var y2 = ofs.top + trashEl.outerHeight(true);
if (currentMousePos.x >= x1 && currentMousePos.x <= x2 &&
currentMousePos.y >= y1 && currentMousePos.y <= y2) {
return true;
}
return false;
}
});
process.php
<?php
define('__ROOT__', dirname(dirname(__FILE__)));
require_once __ROOT__.'/main/metodi.php';
include('config.php');
sec_session_start();
$type = $_POST['type'];
if($type == 'new')
{
$startdate = $_POST['startdate'].'+'.$_POST['zone'];
$title = $_POST['title'];
$zona_servizio = $_POST['zona_servizio'];
$insert = mysqli_query($con,"INSERT INTO calendar(`title`, `startdate`, `enddate`, `allDay`, `zona_servizio`) VALUES('$title','$startdate','$startdate','false','$zona_servizio')");
$lastid = mysqli_insert_id($con);
$_SESSION['array_last_events'][] = $lastid;
echo json_encode(array('status'=>'success','eventid'=>$lastid));
}
if($type == 'changetitle')
{
$eventid = $_POST['eventid'];
$title = $_POST['title'];
$update = mysqli_query($con,"UPDATE calendar SET title='$title' where id='$eventid'");
if($update)
echo json_encode(array('status'=>'success'));
else
echo json_encode(array('status'=>'failed'));
}
if($type == 'resetdate')
{
$title = $_POST['title'];
$startdate = $_POST['start'];
$enddate = $_POST['end'];
$eventid = $_POST['eventid'];
$update = mysqli_query($con,"UPDATE calendar SET title='$title', startdate = '$startdate', enddate = '$enddate' where id='$eventid'");
if($update)
echo json_encode(array('status'=>'success'));
else
echo json_encode(array('status'=>'failed'));
}
if($type == 'remove')
{
$eventid = $_POST['eventid'];
$delete = mysqli_query($con,"DELETE FROM calendar where id='$eventid'");
if($delete)
echo json_encode(array('status'=>'success'));
else
echo json_encode(array('status'=>'failed'));
}
if($type == 'fetch')
{
$events = array();
$query = mysqli_query($con, "SELECT calendar.id, calendar.title, calendar.startdate, calendar.enddate, zona_servizio.nome as zona_servizio, calendar.allDay FROM calendar LEFT JOIN zona_servizio on calendar.zona_servizio = zona_servizio.id");
while($fetch = mysqli_fetch_array($query,MYSQLI_ASSOC))
{
$e = array();
$e['id'] = $fetch['id'];
$e['title'] = $fetch['title'];
$e['start'] = $fetch['startdate'];
$e['end'] = $fetch['enddate'];
$e['zona_servizio'] = $fetch['zona_servizio'];
$allday = ($fetch['allDay'] == "true") ? true : false;
$e['allDay'] = $allday;
array_push($events, $e);
}
echo json_encode($events);
}
if($type == 'zone_servizio')
{
$zone = array();
$query = mysqli_query($con, "SELECT * FROM zona_servizio");
while($fetch = mysqli_fetch_array($query,MYSQLI_ASSOC))
{
$e = array();
$e['id'] = $fetch['id'];
$e['nome'] = $fetch['nome'];
$e['id_comune'] = $fetch['id_comune'];
array_push($zone, $e);
}
echo json_encode($zone);
}
?>
Explanation of the code and issue: I'm using fullcalendar to drag and drop some events on the calendar. In the javascript this corresponds to Event receive. After the event drop, the function saveEvent is called. A modal is showed, with a select form. Clicking on Save changes button, I get the selected option value and than I store the events information and this value in the DB using Ajax. It's very linear. When I drop the first event, everything works fine. The problem is when I drop more than one event without manually refresh the page. Here what happen: I store the second event, but I re-store the first event too. If I drop a third event, I re-store the first two events and the third. I need help to understand the reason. In the javascript I insert some console.log. Here's the console output: console_output
You can see at the end that the console.log "before save event" is repeated two times, with the first and second events data. This means that at the second Event drop, the saveEvent function is called twice. So why does this happen?
I hope my question was clear. Thanks to everyone!