I am using fullcalendar, I need need to create a new event when user clicks on a specific date, I am using Laravel controller to store the data send by ajax request. I can create an event on calendar, but I cant send the data to controller and moreover browser tab freezes after creating the event. Anyone can correct where I am wrong? or provide better solution to the problem.
select: function(start, end, allDay) {
var title = event_name;// Event Title:
var eventData;
if (title) {
eventData = { //creates a new event on the calendar
title: title,
start: start,
end: end,
allDay: allDay
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
$.ajax({
data:eventData,
type: 'POST',
url:"/projects/calendar/store", // your url
beforeSend: function (request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='csrf-token']").attr('content'));
},
success: function(response) {
console.log(response);
}
});
}
$('#calendar').fullCalendar('unselect');
},
This is my Route file, I have tried both get and post but none is working.
Route::get('/projects/calendar/store','FrontEndController#calendarStore');
This is the Controller, it will only process data sent by ajax request but no view.
public function calendarStore(Request $request)
{
$calendar = new Calendar;
Input::all();
$userId = Auth::user()->id;
$event_title =$request->input('title');
$start =$request->input('start');
$end =$request->input('end');
$calendar_event = Calendar::create([
'user_id' => $userId, // I can get the user ID
'project_id' => 2,
'event_title' => $event_title,
'start_date' =>$start,
'end_date' => $end
]);
}
replace your declaration of your ajax data parameter like this:
//creates a new event on the calendar
eventData = {
"title": title,
"start": start,
"end": end,
"allDay": allDay
};
I did the following modifications: and its working as Expected, once user click/selects on the specific day/day's it will ask for title and and save the event in database.
select: function(start, end, allDay) {
var title = prompt('Are u sure you want to apply for job? Yes/No:');// Event Title:
var start_time = moment(start).format();
var end_time = moment(end).format(); //onclick get date
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end,
allDay: allDay
};
$('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
$.ajax({
type: 'GET',//POST changed to GET
url: "/projects/calendar/store", // your url
data: { //event data from global variable
title: event_name,
start: start_time,
end: end_time,
event_id:event_id
},
beforeSend: function (request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='csrf-token']").attr('content'));
},
success: function(response) {
console.log(response);
}
});
}
$('#calendar').fullCalendar('unselect');
},
Updated Route
Route::get('/projects/calendar/store','FrontEndController#calendarStore');
Updated Controller
public function calendarStore(Request $request)
{
$userId = Auth::user()->id;
$event_title =$request->get('title');
$start =$request->input('start');
$end =$request->input('end');
$project_id= $request->input('event_id');
$calendar_event = Calendar::create([
'user_id' => $userId,
'project_id' => $project_id,
'event_title' => $event_title,
'start_date' =>$start,
'end_date' => $end
]);
return $calendar->all();
}
Related
i´m traying to load #include() blade in other blade in laravel after response ok in ajax. I´m doing a statistics in tab pane and i need send data to my controller, for this i´m doing ajax i have this ajax:
$("#createStatistcs").on('click', function(){
let fromDate = $("#fromDate").val();
let toDate = $("#toDate").val();
let token = $('meta[name=csrf-token]').attr('content');
$.ajax({
type: 'GET',
url: "{{ route('admin.llamadas.estadisticas') }}",
data: { 'fromDate': fromDate, 'toDate': toDate },
success: function(response){
},
error: function(xhr){
alert(xhr.responseText);
}
});
})
and i have this in my controller:
public function index(Request $request)
{
$estadosLlamadas = EstadoLlamada::orderBy('desc')->get();
if(isset($request->fromDate) && isset($request->toDate)){
$fromDate = Carbon::parse($request->get('fromDate'));
$toDate = Carbon::parse($request->get('toDate'));
$fromDate = $fromDate->format('Y-m-d');
$toDate = $toDate->format('Y-m-d');
}else{
$fromDate = new Carbon('first day of this month');
$toDate = new Carbon('last day of this month');
$fromDate = $fromDate->format('Y-m-d');
$toDate = $toDate->format('Y-m-d');
}
$teleoperadoras = auth()->user()->whereIs('teleoperadora')->activos()->select(['id', 'nombre'])->orderBy('nombre', 'desc')->get();
$array = [
'toDate' => $toDate,
'fromDate' => $fromDate,
'nombresEstados' => $estadosLlamadas->pluck('desc')->toArray(),
'coloresEstados' => $estadosLlamadas->pluck('hex')->toArray()
];
$query = Llamada::query()
->whereDate('llamada.created_at', '<=', $toDate)
->whereDate('llamada.created_at', '>=', $fromDate)
->whereIn('llamada.id_teleoperadora', $teleoperadoras->pluck('id'))
->join('users', 'llamada.id_teleoperadora', '=', 'users.id')->latest('llamada.created_at')->get();
foreach($teleoperadoras as $teleoperadora) {
$array['teleoperadoras'][] = $teleoperadora->nombre;
$array['id_teleoperadoras'][] = $teleoperadora->id;
$array[$teleoperadora->id]['resultados'] = [];
$array['llamadas'][] = $query->where('id_teleoperadora', $teleoperadora->id)->count();
$array['llamadasTodo'][$teleoperadora->id] = $query->where('id_teleoperadora', $teleoperadora->id);
foreach($estadosLlamadas as $estado) {
$array[$teleoperadora->id]['resultados'][] = $query->where('id_teleoperadora', $teleoperadora->id)->where('id_estado', $estado->id)->count();
}
}
$array['nllamadas'] = $query->count();
$roleUser = auth()->user()->getRoles()->first();
$view = view('admin.llamadas.filtrado', [
'datos' => $array, 'estados' => $estadosLlamadas,
'teleoperadoras' => $teleoperadoras, 'roleUser' => $roleUser,
])->render();
echo response()->json(['html'=>$view]);
}
this function return all data i need. But i want that don´t reload my page and generate graphic in this view.
i´m traying this, don´t return error, but return nothing. I´m reading in google and many people say that use ->render() but i can´t show result
Thanks for help me and readme
If you have a div in your template where you want this blade view to be displayed, you can do:
$("#createStatistcs").on('click', function(){
let fromDate = $("#fromDate").val();
let toDate = $("#toDate").val();
let token = $('meta[name=csrf-token]').attr('content');
$.ajax({
type: 'GET',
url: "{{ route('admin.llamadas.estadisticas') }}",
data: { 'fromDate': fromDate, 'toDate': toDate },
success: function(response){
$('your-element').html(response.html);
},
error: function(xhr){
alert(xhr.responseText);
}
});
})
I have a calendar.php file which looks up "php/get-events" to display calendar events from the database (This currently works as expected). I am trying to use "php/calendarupdate" to then update the database with the new start/end times that have been dragged, but the data posting to this page always comes back as undefined, so it's not finding it for some reason.
"Calendar.php"
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
initialDate: '2021-03-18',
editable: true,
eventDrop: function(event, delta) {
start=moment(event.start).format('Y-MM-DD HH:mm:ss');
end=moment(event.end).format('Y-MM-DD HH:mm:ss');
$.ajax({
url: 'php/calendarupdate.php',
data: 'title=' + event.title + '&start='+ event.start +'&end=' + event.end + '&id=' + event.id ,
type: "POST",
success: function(json) {
alert("Updated Successfully");
}
});
},
navLinks: true, // can click day/week names to navigate views
dayMaxEvents: true, // allow "more" link when too many events
events: {
url: '/php/get-events.php',
failure: function() {
document.getElementById('script-warning').style.display = 'block'
}
},
loading: function(bool) {
document.getElementById('loading').style.display =
bool ? 'block' : 'none';
}
});
calendar.render();
});
</script>
The following is where I get the data which successfully displays events on the calendar.
"php/get-events.php"
$stmt = $pdo->prepare("Select id,task_name,start,end,notes,task_type,status from tasks where attendees like ".$attendees);
$stmt->execute();
//$stmt->debugDumpParams();
foreach ($stmt as $row){
$rawdata[] = array('id' => $row['id'], 'title'=> $row['task_name'], 'start'=> $row['start'], 'end'=> $row['end']);
}
$rawdata = json_encode($rawdata);
echo $rawdata;
The following is the update file, which it is getting into ok, but the echo's I try to display are all undefined.
/* Values received via ajax */
echo "id -".$_POST['id'];
echo "start -".$_POST['start'];
echo "end -".$_POST['end'];
// update the records
$stmt = $pdo->prepare('UPDATE tasks SET start=?, end=? WHERE id=?');
$stmt->execute($_POST['start'], $_POST['end'], $_POST['id']);
$stmt->debugDumpParams();
It may be something simple, but from the documentation I've read, I can't seem to figure out why my variables are not posting successfully. Thanks.
You have the wrong syntax for your eventDrop signature. See https://fullcalendar.io/docs/eventDrop
It should be
eventDrop: function(info) {
And then replace
event.start
and
event.end
with
info.event.start
and
info.event.end
This will get the information you need correctly from the data which fullCalendar supplies.
I am building a college timetable with FullCalendar, php and mysql.
Events are created when you click in the calendar field; you assign a name for the event, a professor and a room. The event is saved in an sql databse.
I would like to add a search bar which would search through the timetable; a user could search for either professor, room number, event name. The timetable would update as the user types and it would re-fetch the event with that room number/event name/professor name.
Anyone have any clue how to do this?
This is the code i am using for rendering events from the mysql:
$sql = "SELECT id, title, naem, mentor, start, end, color FROM events ";
$req = $bdd->prepare($sql);
$req->execute();
$events = $req->fetchAll();
...
...
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
height:595,
defaultView: 'agendaWeek',
minTime: "07:00:00",
maxTime: "16:00:00",
editable: true,
eventLimit: true,
selectable: true,
selectHelper: true,
firstDay:"1",
select: function(start, end) {
$('#ModalAdd #start').val(moment(start).format('YYYY-MM-DD HH:mm:ss'));
$('#ModalAdd #end').val(moment(end).format('YYYY-MM-DD HH:mm:ss'));
$('#ModalAdd').modal('show');
},
eventRender: function(event, element) {
element.bind('dblclick', function() {
$('#ModalEdit #id').val(event.id);
$('#ModalEdit #title').val(event.title);
$('#ModalEdit #naem').val(event.naem);
$('#ModalEdit #mentor').val(event.mentor);
$('#ModalEdit #color').val(event.color);
$('#ModalEdit').modal('show');
});
element.find('.fc-title').append("<br/>" + event.naem + "<br/>" + event.mentor);
},
eventDrop: function(event, delta, revertFunc) {
edit(event);
},
eventResize: function(event,dayDelta,minuteDelta,revertFunc) {
edit(event);
},
events: [
<?php foreach($events as $event):
$start = explode(" ", $event['start']);
$end = explode(" ", $event['end']);
if($start[1] == '00:00:00'){
$start = $start[0];
}else{
$start = $event['start'];
}
if($end[1] == '00:00:00'){
$end = $end[0];
}else{
$end = $event['end'];
}
?>
{
id: '<?php echo $event['id']; ?>',
title: '<?php echo $event['title']; ?>',
naem: '<?php echo $event['naem']; ?>',
mentor: '<?php echo $event['mentor']; ?>',
start: '<?php echo $start; ?>',
end: '<?php echo $end; ?>',
color: '<?php echo $event['color']; ?>',
},
<?php endforeach; ?>
]
});
function edit(event){
start = event.start.format('YYYY-MM-DD HH:mm:ss');
if(event.end){
end = event.end.format('YYYY-MM-DD HH:mm:ss');
}else{
end = start;
}
id = event.id;
Event = [];
Event[0] = id;
Event[1] = start;
Event[2] = end;
$.ajax({
url: 'editEventDate.php',
type: "POST",
data: {Event:Event},
success: function(rep) {
if(rep == 'OK'){
alert('Spremljeno!');
}else{
alert('Nešto zajebaje...');
}
}
});
}
});
</script>
An autocomplete plugin such as this will help with the UI part: https://jqueryui.com/autocomplete/
Using this your user can find the IDs of the people / rooms / event names involved and choose one from the list of possibilities. You will need an ajax call and an associated server endpoint which will search the database based on what the user types into the box and return any matching results.
Then in fullCalendar use this format for your event feed https://fullcalendar.io/docs/event_data/events_function/ so that you can pass the selected ID from the autocomplete to the server as an extra parameter when fetching events.
Next listen to the autocomplete's "select" event (http://api.jqueryui.com/autocomplete/#event-select) and when a value is chosen, call "refetchEvents" (https://fullcalendar.io/docs/event_data/refetchEvents/) on the fullCalendar. This will update your events list, restricting it by the specific person/room/event ID as well as the standard parameters (i.e. those being the current start/end dates of the visible view).
I've got 6 different routes that can be chosen from an input select. Each selected route then posts to its own database.
The problem is I get a 500 error back for all of them, but on half of them, it actually posts to the database. I've gone through line-by-line, and other than the variable names, the code is identical. Here's an example of one that doesn't work at all.
submit.js
$('#submit-event').on('click', function() {
event.preventDefault()
let title = $('#title').val()
let type = $('#type').val() // for selecting which DB
let start = $('#start').data('DateTimePicker').date()
let end = $('#end').data('DateTimePicker').date()
let data = {
'_token': token,
'title': title,
'start': start,
'end': end
}
console.log(type); // logs the correct POST route
$.ajax({
method: 'POST',
url: type,
data: data,
success: function(data) {
console.log(data);
},
error: function(err) {
console.log(err)
}
});
})
routes.php
Route::post('/createmeeting', [
'uses' => 'MeetingController#postCreateMeeting',
'as' => 'createmeeting'
]);
MeetingController.php
class MeetingController extends Controller
{
// Get Meeting from DB - works
public function getMeetings()
{
$meetings = Meeting::orderBy('created_at', 'desc')->get();
return $meetings;
}
// Add new Meeting to DB - doesn't work (500 error)
public function postCreateMeeting(Request $request)
{
if (!request['_token']) {
return redirect()->route('calendar')->with(['message' => "You must be logged in"]);
}
// Save Meeting
$meeting = new Meeting();
$meeting->title = $request['title'];
$meeting->start = $request['start'];
$meeting->end = $request['end'];
if ($request->user()->meetings()->save($meeting)) {
$message = 'Event successfully added to calendar';
return redirect()->route('calendar')->with(['message' => $message]);
}
return redirect()->route('calendar')->with(['message' => $message]);
}
}
Responses to similar problems suggest a problem with the token, but I test for that here. Any idea where the mistake could be happening?
I've been trying for days to get this working and I just cannot figure out why when I have my view to destroy a model which belongs to a collection (which properly has a url attribute for the beginning fetch of models' data), only fires the destroy 'event' which is bubbled up to the collection for easy binding by my list view. But it does not ever send an actual DELETE request or any request to the server at all. Everywhere I look, I see everyone using either the collection's url attr, or urlRoot if the model is not connected to a collection. I've even tested before the actual this.model.destroy() to check the model < console.log(this.model.url());
I have not overwritten the destroy nor sync methods for backbone. Also each model does have an id attribute which is populated via the collection's fetch (from database records).
The destroy takes place in the list item view, and the collection's "destroy" event is bound in the list view. All that works well (the event handling), but the problem, again, is there's no request to the server.
I was hoping that backbone.js would do it automatically. That was what the documentation implies, as well as the numerous examples everywhere.
Much thanks to anyone who can give some useful input.
FYI: I'm developing on wampserver PHP 5.3.4.
ListItemView = BaseView.extend({
tagName: "li",
className: "shipment",
initialize: function (options) {
_.bindAll(this);
this.template = listItemTemplate;
this.templateEmpty = listItemTemplateEmpty;
},
events: {
'click .itemTag' : 'toggleData',
'click select option' : 'chkShipper',
'click .update' : 'update',
'click button.delete' : 'removeItem'
},
// ....
removeItem: function() {
debug.log('remove model');
var id = this.model.id;
debug.log(this.model.url());
var options = {
success: function(model, response) {
debug.log('remove success');
//debug.log(model);
debug.log(response);
// this.unbind();
// this.remove();
},
error: function(model, response) {
debug.log('remove error');
debug.log(response);
}
};
this.model.destroy(options);
//model.trigger('destroy', this.model, this.model.collection, options);
}
});
Collection = Backbone.Collection.extend({
model: Model,
url: '?dispatch=get&src=shipments',
url_put : '?dispatch=set&src=shipments',
name: 'Shipments',
initialize: function () {
_.bindAll(this);
this.deferred = new $.Deferred();
/*
this.fetch({
success: this.fetchSuccess,
error: this.fetchError
});
*/
},
fetchSuccess: function (collection, response) {
collection.deferred.resolve();
debug.log(response);
},
fetchError: function (collection, response) {
collection.deferred.reject();
debug.log(response);
throw new Error(this.name + " fetch failed");
},
save: function() {
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: this.url_put,
toJSON: function() {
return that.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
updateModels: function(newData) {
//this.reset(newData);
}
});
ListView = BaseView.extend({
tagName: "ul",
className: "shipments adminList",
_viewPointers: {},
initialize: function() {
_.bindAll(this);
var that = this;
this.collection;
this.collection = new collections.ShipmentModel();
this.collection.bind("add", this.addOne);
this.collection.fetch({
success: this.collection.fetchSuccess,
error: this.collection.fetchError
});
this.collection.bind("change", this.save);
this.collection.bind("add", this.addOne);
//this.collection.bind("remove", this.removeModel);
this.collection.bind("destroy", this.removeModel);
this.collection.bind("reset", this.render);
this.collection.deferred.done(function() {
//that.render();
that.options.container.removeClass('hide');
});
debug.log('view pointers');
// debug.log(this._viewPointers['c31']);
// debug.log(this._viewPointers[0]);
},
events: {
},
save: function() {
debug.log('shipments changed');
//this.collection.save();
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: that.collection.url_put,
toJSON: function() {
return that.collection.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
addOne: function(model) {
debug.log('added one');
this.renderItem(model);
/*
var view = new SB.Views.TicketSummary({
model: model
});
this._viewPointers[model.cid] = view;
*/
},
removeModel: function(model, response) {
// debug.log(model);
// debug.log('shipment removed from collection');
// remove from server
debug.info('Removing view for ' + model.cid);
debug.info(this._viewPointers[model.cid]);
// this._viewPointers[model.cid].unbind();
// this._viewPointers[model.cid].remove();
debug.info('item removed');
//this.render();
},
add: function() {
var nullModel = new this.collection.model({
"poNum" : null,
"shipper" : null,
"proNum" : null,
"link" : null
});
// var tmpl = emptyItemTmpl;
// debug.log(tmpl);
// this.$el.prepend(tmpl);
this.collection.unshift(nullModel);
this.renderInputItem(nullModel);
},
render: function () {
this.$el.html('');
debug.log('list view render');
var i, len = this.collection.length;
for (i=0; i < len; i++) {
this.renderItem(this.collection.models[i]);
};
$(this.container).find(this.className).remove();
this.$el.prependTo(this.options.container);
return this;
},
renderItem: function (model) {
var item = new listItemView({
"model": model
});
// item.bind('removeItem', this.removeModel);
// this._viewPointers[model.cid] = item;
this._viewPointers[model.cid] = item;
debug.log(this._viewPointers[model.cid]);
item.render().$el.appendTo(this.$el);
},
renderInputItem: function(model) {
var item = new listItemView({
"model": model
});
item.renderEmpty().$el.prependTo(this.$el);
}
});
P.S... Again, there is code that is referenced from elsewhere. But please note: the collection does have a url attribute set. And it does work for the initial fetch as well as when there's a change event fired for saving changes made to the models. But the destroy event in the list-item view, while it does trigger the "destroy" event successfully, it doesn't send the 'DELETE' HTTP request.
Do your models have an ID? If not, the HTTP request won't be sent. –
nikoshr May 14 at 18:03
Thanks so much! Nikoshr's little comment was exactly what I needed. I spent the last 5 hours messing with this. I just had to add an id to the defaults in my model.