I'm in the middle of developing a drag and drop event fullcalendar with a resource column. I'm able to drag and drop events on the calendar and save it to the database. For the resource column, I have an add room button that allows users to add the room which also gets saved in the database. The resources and events are successfully being fetched and displayed on the calendar.
Now, I'm working on developing the delete functionality for the same. For now, I'm stuck at deleting the events using a double click.
Here's the code:
main.js
document.addEventListener("DOMContentLoaded", function() {
var containerEl = document.getElementById("external-events");
var checkbox = document.getElementById("drop-remove");
new FullCalendarInteraction.Draggable(containerEl, {
itemSelector: ".fc-event",
eventData: function(eventEl) {
return {
title: eventEl.innerText
};
}
});
var calendarEl = document.getElementById("calendar");
var calendar = new FullCalendar.Calendar(calendarEl, {
schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
plugins: ["interaction", "resourceTimeline", 'dayGrid', 'timeGrid' ],
header: {
left: "promptResource today prev,next",
center: "title",
right: 'dayGridMonth,resourceTimelineDay,resourceTimelineWeek'
},
customButtons: {
promptResource: {
text: "+ room",
click: function() {
var title = prompt("Room name");
console.log(title);
if (title) {
fetch("add_resources.php", {
method: "POST",
headers: {
'Accept': 'text/html'
},
body: encodeFormData({"title": title}),
})
.then(response => response.text())
.then(response => {
calendar.addResource({
id: response,
title: title
});
})
.catch(error => console.log(error));
}
}
}
},
editable: true,
aspectRatio: 1.5,
defaultView: "resourceTimelineDay",
resourceLabelText: "Rooms",
resources: "all_resources.php",
droppable: true,
drop: function(info) {
if (checkbox.checked) {
info.draggedEl.parentNode.removeChild(info.draggedEl);
}
},
eventLimit: true,
events: "all_events.php",
displayEventTime: false,
eventRender: function(event, element, view) {
if (event.allDay === "true") {
event.allDay = true;
} else {
event.allDay = false;
}
},
selectable: true,
selectHelper: true,
eventClick: function (info) {
var confimit = confirm("Do you really want to delete?");
if (confimit) {
$.ajax({
type: "POST",
url: "delete_event.php",
data: "&id=" + info.event.id,
success: function (response) {
if(parseInt(response) > 0) {
$('#calendar').fullCalendar('removeEvents', info.event.id);
displayMessage("Deleted Successfully");
}
}
});
}
},
eventReceive: function(info) {
console.log(calendar.getResources());
console.log(info.event);
var eventData = {
title: info.event.title,
start: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
end: moment(info.event.start).format("YYYY-MM-DD HH:mm"),
resourceid: info.event._def.resourceIds[0]
};
console.log(eventData);
//send the data via an AJAX POST request, and log any response which comes from the server
fetch("add_event.php", {
method: "POST",
headers: {
Accept: "application/json"
},
body: encodeFormData(eventData)
})
.then(response => console.log(response))
.catch(error => console.log(error));
}
});
calendar.render();
});
const encodeFormData = data => {
var form_data = new FormData();
for (var key in data) {
form_data.append(key, data[key]);
}
return form_data;
};
delete_event.php
<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
if ($stmt->execute()) {
return $stmt->fetch(PDO::FETCH_ASSOC);
} else {
return null;
}
?>
When I'm trying to delete an event using the above code, I double click on the event, I see the message asking if I really want to delete the event, but it doesn't really get deleted. I don't see the delete_event.php being called in the network panel. The console has the error "ReferenceError: $ is not defined". I'm not sure what is wrong in the code above.
You need to make a few modifications to your code.
1) use fetch() instead of $.ajax, then you won't get any error messages about jQuery being missing. Ensure you put the event ID into the body of the request.
2) use the fullCalendar v4 syntax for eventClick, instead of v3 - see https://fullcalendar.io/docs/eventClick.
3) Remove the $stmt->fetch command from your PHP - a SQL DELETE operation doesn't return any results, so there is nothing to fetch. I also removed the meaningless return statements, because you're not inside a function, and your script doesn't have any further code which needs to be prevented from executing.
eventClick:
eventClick: function (info) {
var confimit = confirm("Do you really want to delete?");
if (confimit) {
fetch("delete_event.php", {
method: "POST",
body: encodeFormData({"id": info.event.id}) });
}
}
}
delete_event.php:
<?php
require "connection.php";
$id = $_POST['id'];
$conn = DB::databaseConnection();
$sql = "DELETE FROM Events WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':id', $id);
if ($stmt->execute()) {
echo true;
} else {
echo false;
}
?>
Related
my Controller :
public function eventCalender(){
$eventCalender = [
'title' => 'Matts Booking',
'start' => '2019-05-05',
];
$response = [
'eventCalender' => $eventCalender,
'status' => 1,
];
return response()->json($response);
}
my js file :
function getEventCalender() {
var actionurl = base_url + "/events/event-calender";
$.ajax({
type: "GET",
url: actionurl,
success: function (res) {
if (res['status'] == 1) {
$("#event-list").hide();
$("#calender-list").show();
} else {
console.log("Something went wrong!!!!");
}
},
error: function (jqXHR, exception) {
$("#errormsg").show();
}
});
}
$(document).ready(function () {
getEventCalender();
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['interaction', 'dayGrid', 'list', 'googleCalendar'],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,listYear'
},
defaultDate: '2019-03-12',
navLinks: true,
businessHours: true,
editable: true,
event: res.eventCalender,
});
calendar.render();
});
});
so this is my controller and js file what i want is when i get data from controller how do i print that data in calendar ?
and i am using fullcalendar so when i add
document.addEventListener('DOMContentLoaded', function () { }
this function then only my calendar show in page.
If i put above function out of getEventCalender() function then my calender show perfectly but when i put it in getEventCalender() function like shown above it doesn't show my calendar.
Call the getEventCalender() in a document ready function to execute after all the content has loaded
$(function() {
getEventCalender();
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
The below function is working fine and I am getting response from ajax get function, the data is comming in 'res.data.value' in JSON format, Now i want to pass this data to events property of full calender in array format. If i am passing static values to events property it is working fine. Please help me as I am unable to pass 'res.data.value' value dynamically.
<script>
$(document).ready(function() {
var completedInterviews = function() {
var requestParams = [];
requestParams = {
"url": dashboardServiceUrl + '/dashboard/widget/completedinterview',
"requestType": "GET",
"headers": {
"Accept": "application/json"
}
}
var res = makeRequest(requestParams);
res
.done(function(res) {
return [res.data.value];
})
.fail(function(err) {
console.log(err);
});
};
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
defaultDate: '2018-03-12',
editable: true,
navLinks: true,
eventLimit: true,
events: completedInterviews(), // I want [res.data.value] value here.
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
</script>
/*
* function to make API call using AJAX, Deffered and Promise
*/
function makeRequest(requestParams) {
var headers = {
'Authorization': 'Bearer ' + authToken
};
// concating extra headers
headers = jsonConcat(headers, requestParams.headers);
// checking return content type
var dataType = "json";
if(headers.Accept == "application/xml") {
dataType = "xml";
}
var deferred = $.Deferred();
var response = $.ajax({
url: requestParams.url,
type: requestParams.requestType,
dataType: dataType,
data: JSON.stringify(requestParams.params),
headers: headers,
success: function(res) {
if(res.error != null) {
deferred.reject(res.error);
if(res.error=="Invalid Token") {
//window.location.href = "";
}
} else {
deferred.resolve(res);
}
},
error: function(err) {
deferred.reject(err);
}
});
return deferred.promise();
}
Use calendar in then statement.
<script>
$(document).ready(function() {
var completedInterviews = function() {
var requestParams = [];
requestParams = {
"url": dashboardServiceUrl + '/dashboard/widget/completedinterview',
"requestType": "GET",
"headers": {
"Accept": "application/json"
}
}
res = makeRequest(requestParams);
//RETURN RES
return res;
};
//WRAP CALENDAR WITH THEN
completedInterviews().then(function(data){
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listWeek'
},
defaultDate: '2018-03-12',
editable: true,
navLinks: true,
eventLimit: true,
events: data, // ADD DATA.
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
});
</script>
Hi I am trying to make an save / create an item using ajax.
I am not that familiar with ajax and wanted to ask which steps I have to do next to make the save / create function make work.
How do I get the data and save it in my database.
So far my ajax code looks like this:
$(document).ready(function() {
$("#save-item").click(function(e) {
e.preventDefault();
var id = $('#item-id').data('item-id');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
}
});
$.ajax({
url: 'joke/create',
type: 'post',
data: {
id: id,
content: $('#item').val()
},
success: function(data) {
console.log("Success with data " + data);
},
error: function(data) {
console.log("Error with data " + data);
}
});
});
});
And my Controller looks like this:
public function create(Request $request)
{
$item = new Item;
if($data->save())
{
return response()->json(["response" => 200, "joke" => $item]);
}
else
{
return response()->json(["response" => 400, "joke" => $item]);
}
}
try this inside your controller:
$item = new Item;
$data = $request->all();
$item->create($data);
$item = new Item;
$data = $request->all();
if($item->create($data))
{
return response()->json(["response" => 200, "joke" => $item]);
}
else
{
return response()->json(["response" => 400, "joke" => $item]);
}
I'm working on a fullcalendar module for my page.I could display Events on calendar without the recurring feature. But when I altered my table to include recurring features I could not display events from the table.
This is my table structure.
The Update function in controller is called while the form is submitted and i noticed that it is being updated in the table.This is my form.
and this is my controller update function.
public function update($id)
{
//$type=Input::get('type');
$event_id= Input::get('eventid');
$title= Input::get('title');
$start_day=Input::get('start');
$end_day=Input::get('end');
$allday=Input::get('allday');
$repeat=Input::get('repeat');
$frequency=Input::get('frequency');
$start_time=Input::get('start_time');
$end_time=Input::get('end_time');
$dow=Input::get('dow');
$month=Input::get('month');
$weekly_json=json_encode($dow);
$monthly_json=json_encode($month);
$newstrt=substr($start_day,0,10);
$newend=substr($end_day,0,10);
$start= date("Y-m-d H:i:s",$newstrt);
$end= date("Y-m-d H:i:s" , $newend);
$roles = DB::table('events')
->where('event_id','=',$event_id)
->update(array('title' => $title,'daily'=>$allday,'repeat'=>$repeat,'frequency'=>$frequency,'start'=>$start,'end'=>$end,'time'=>$time,'dow'=>$weekly_json,'monthly_json'=>$monthly_json));
if (Request::ajax())
{
return Response::json(array('id'=>$event_id,'title'=>$title,'newstrt'=>$start,'newend'=>$end,'start_time'=>$start_time,'end_time'=>$end_time));
}
else
{
return Redirect::route('calendar.index');
}
}
But I'm not being able to display these details on the full calendar.I was following this link to implement recurring events on fullcalendar.
Recurring Events in FullCalendar.
This is my index function used for GETting details from the table.
public function index()
{
$event = DB::table('events')
->leftJoin('people','people.people_id','=','events.people_id')
->where('events.flag', '=', 1)
->get(array('events.event_id','events.title','events.start','events.end','events.start_time','events.end_time','events.repeat','events.frequency','events.dow'));
$id=array(array());
$temp = array(array());
$i=0;
foreach ($event as $events)
{
$j=0;
$id[$i]["event_id"]=$events->event_id;
$id[$i]["title"]=$events->title;
$temp[$j]['start']=$events->start;
$temp[$j]['end'] = $events->end;
$temp[$j]['start_time']=$events->start_time;
$temp[$j]['end_time'] = $events->end_time;
$start_json=json_encode($temp);
$id[$i]['range'] = $start_json;
$id[$i]["frequency"]=$events->frequency;
$id[$i]["repeat"]=$events->repeat;
$id[$i]["dow"]=$events->dow;
$i++;
}
return Response::json($id);
}
This is my calendar eventrender function and events structure.
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var repeatingEvents = [{
url: '/v1/calendar/',
type: 'GET',
ranges: [{ //repeating events are only displayed if they are within 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'),
}],
}];
console.log(repeatingEvents);
var getEvents = function( start, end ){
return repeatingEvents;
}
var calendar=$('#calendar');
$.ajax({
url: '/v1/calendar/',
type: 'GET',
dataType:'json',
success:function events(response)
{
console.log(response);
calendar.fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
eventRender: function(event, element, view){
console.log(event.start.format());
return (event.range.filter(function(range){
return (event.start.isBefore(range.end) &&
event.end.isAfter(range.start));
}).length)>0;
},
events: function( start, end, timezone, callback ){
var events = getEvents(start,end); //this should be a JSON request
callback(events);
},
editable: true,
droppable: true, // this allows things to be dropped onto the calendar
drop: function() {
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
eventSources: [
{
url: '/v1/calendar/',
type: 'GET',
dataType:'json',
},
calendar.fullCalendar( 'addEventSource', response )
],
selectable: true,
selectHelper: true,
select: function(start, end, allDay)
and I am getting JSON response like this on the console.
dow: "{[0,1,2]↵}"
event_id: 1
frequency: "weekly"
range: "[{"start":"2015-09-11","end":"2015-09-12","start_time":"11:00:00","end_time":"15:00:00"}]"
repeat: 1
title: "Youth festival"
I get no errors on the console....but the events aren't displayed too..
where did i go wrong? Helps guys?
See this code, i am also facing
After that I use this idea ,its working
In Controller
$vendor_holiday = Vendor::all();
return view('vendorpanel/holidays/index', compact('vendor_holiday'));
<script>
var calendar = $('#calendar').fullCalendar({
editable: false,
header: {
left: 'prev,next today',
center: 'title',
right: 'month'
},
events: [
#foreach($vendor_holiday as $vendor_holiday)
{
title : "",
start : '{{ $vendor_holiday->start }}',
},
#endforeach
],
selectable: true,
selectHelper: true,
select: function (start, end, allDay) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var start = moment(start).format('YYYY-MM-DD');
var end = moment(end).format('YYYY-MM-DD');
var vendor_id = $("#vendor_id").val();
var tdate = new Date();
var dd = tdate.getDate(); //yields day
var MM = tdate.getMonth(); //yields month
var yyyy = tdate.getFullYear(); //yields year
var currentDate= yyyy+ "-" +0+( MM+1) + "-" + dd;
if(start <= currentDate){
alert("Mark Holiday at least 1 day before");
return false;
}
if (confirm("Are you sure you want to Add a Holiday?")) {
$.ajax({
url: "/vendor/holidays",
type: "POST",
data: { vendor_id: vendor_id, start: start, end: end },
success: function (d) {
calendar.fullCalendar('refetchEvents');
alert(d);
location.reload();
},
})
}
},
eventClick: function (calEvent, jsEvent, view, event) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
if (confirm("Are you sure you want to remove it?")) {
var start = calEvent.start.format();
var vendor_id = $("#vendor_id").val();
$.ajax({
url: '/vendor/holidays/'+vendor_id,
type: "DELETE",
data: { _method: 'delete', start: start },
success: function (d) {
$('#calendar').fullCalendar('removeEvents', calEvent._id);
alert(d);
},
error: function (data) {
alert(data);
}
});
}
},
});
</script>
Laravel - Recurring event occurrences generator and organiser.
Calendarful is a simple and easily extendable PHP solution that allows the generation of occurrences of recurrent events, thus eliminating the need to store hundreds or maybe thousands of occurrences in a database or other methods of storage.
This package ships with default implementations of interfaces for use out of the box although it is very simple to provide your own implementations if needs be.
It is compliant with PSR-2.
Installation
This package can be installed via Composer:
https://github.com/Vij4yk/calendarful
$ composer require plummer/calendarful
It requires PHP >= 5.3.0
Try this package.
socket.on('new message', function(data) {
self.createMessage(data);
});
createMessage: function(data) {
setTimeout(function() {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
}, 1000);
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
Let's say for example I have three sockets/users connected. When I run the code above each client makes that GET request three times (as many users that are connected). A bit annoying to me, it works well but I don't like the unnecessary requests.
It's a bit confusing because if I just appended some HTML like this.
createMessage: function(data) {
this.$el.find('.message-content').append('<div class="message"><b>'+data.username+':</b>'+data.message+'</div>');
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
Then that only happens once across all connected sockets/users not three times? But when I fetch GET then it want's to make that request three times, hmm? Any ideas, what am I missing?
Full Code: So there is no confusion
var Marionette = require('backbone.marionette'),
MessagesView = require('./messages'),
socket = io.connect();
module.exports = ChatView = Marionette.ItemView.extend({
className: 'chat',
template: require('../../templates/chat.hbs'),
events: {
'submit #chat-form': 'sendMessage'
},
initialize: function() {
var self = this;
this.messagesView = new MessagesView({ collection: window.App.data.messages });
socket.on('new message', function(data) {
self.createMessage(data);
});
},
onRender: function() {
this.$el.find('.message-content').append(this.messagesView.render().$el);
},
sendMessage: function(e) {
e.preventDefault();
var $message = this.$el.find('input.message');
$email = this.$el.parent().attr('data-email');
$username = this.$el.parent().attr('data-username');
var message = {
email : $email,
username: $username,
message : $message.val()
}
if($message.val() != '') {
socket.emit('send message', $message.val());
window.App.data.messages.create(message);
$message.val('');
}
window.App.core.vent.trigger('app:log', 'Chat View: Sent a new message!');
},
createMessage: function(data) {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
//this.$el.find('.message-content').append('<div class="message"><b>'+data.username+':</b>'+data.message+'</div>');
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
});
So the socket.io and backbone.js combination doesn't seem to popular. It's amazing technology IMO.
Okay so I found a solution, I forgot that while .fetch makes my GET requests, .create makes the POST request.
So by simply adding a call back to the .create method then on success I emit the data to the sockets, then return it to the client and make a GET request to all the sockets. Works like a charm, here is my solution.
var Marionette = require('backbone.marionette'),
MessagesView = require('./messages'),
socket = io.connect();
module.exports = ChatView = Marionette.ItemView.extend({
className: 'chat',
template: require('../../templates/chat.hbs'),
events: {
'submit #chat-form': 'sendMessage'
},
initialize: function() {
var self = this;
this.messagesView = new MessagesView({ collection: window.App.data.messages });
socket.on('new message', function(data) {
self.createMessage(data);
});
},
onRender: function() {
this.$el.find('.message-content').append(this.messagesView.render().$el);
},
sendMessage: function(e) {
e.preventDefault();
var $message = this.$el.find('input.message');
$email = this.$el.parent().attr('data-email');
$username = this.$el.parent().attr('data-username');
var message = {
email : $email,
username: $username,
message : $message.val()
}
if($message.val() != '') {
//window.App.data.messages.create(message);
window.App.data.messages.create({ message }, {
success: function() {
socket.emit('send message', $message.val());
}
});
$message.val('');
}
window.App.core.vent.trigger('app:log', 'Chat View: Sent a new message!');
},
createMessage: function(data) {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
});
This solves all my issues. For one I don't make an emission or any GET requests until the data is successfully on the server. Then after success I emit the data and then the .fetch() method only runs once for each socket!