fullcalendar loaded with ajax symfony2 doctrine2 - ajax

this my function in controller
public function loadcalendarAction() {
$eventsloaded = $this->container->get('calendarbundle.serviceloadcalendar')->loadCalendar();
$response = new JsonResponse();
//dump($eventsloaded);
//die();
$response->setData(array('events' => $eventsloaded));
return $response;
}
the $eventsloaded is an array of 2 events in my database its OK .. but $response is empty i don't know why ..
and this my calendar_setting.js
$(document).ready(function () {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2016-01-12',
lang: 'ar-tn',
buttonIcons: false, // show the prev/next text
weekNumbers: true,
editable: true,
eventLimit: true, // allow "more" link when too many events
dayClick: function () {
alert('a day has been clicked!');
},
events: Routing.generate('loadcalendar')
});
});
if the response not empty all the events will be displayed in the events:

Look at this questions' answer. You need either to use some external bundle (such as JMSSerializerBundle) to serialize entity, to pass it to json response, or implement something like toArray() method in your entity which will return an array of needed data from entity, after that you could do smth like:
$responseData = [];
foreach ($eventsloaded as $i => $event) {
$responseData[$i] = $event->toArray();
}
return new JsonResponse($responseData);

Related

Laravel 8 get data from DB and show in Full calendar JS plugin Not working

Route
Route::get('getEvents', [App\Http\Controllers\CalenderController::class, 'index'])->name('event.getEvents');
Controller
public function index(Request $request)
{
$getEvents = Appointment::select('patient_id', 'start_time', 'end_time')->get();
$events = [];
foreach ($getEvents as $values) {
$start_time_format = $values->start_time;
$end_time_format = $values->end_time;
$event = [];
$event['title'] = $values->patient_id;
$event['start'] = $start_time_format;
$event['end'] = $end_time_format;
$events[] = $event;
Debugbar::info($events);
}
return $events;
}
Full Calendar Script
var calendar = new FullCalendar.Calendar(calendarEl, {
editable: true,
droppable: true,
selectable: true,
initialView: getInitialView(),
themeSystem: 'bootstrap',
// responsive
windowResize: function(view) {
var newView = getInitialView();
calendar.changeView(newView);
},
eventDidMount: function(info) {
if (info.event.extendedProps.status === 'done') {
// Change background color of row
info.el.style.backgroundColor = 'red';
// Change color of dot marker
var dotEl = info.el.getElementsByClassName('fc-event-dot')[0];
if (dotEl) {
dotEl.style.backgroundColor = 'white';
}
}
},
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
eventClick: function(info) {
addEvent.modal('show');
formEvent[0].reset();
selectedEvent = info.event;
$("#event-title").val(selectedEvent.title);
$('#event-category').val(selectedEvent.classNames[0]);
newEventData = null;
modalTitle.text('Edit Event');
newEventData = null;
},
dateClick: function(info) {
addNewEvent(info);
},
editable: true,
events: 'getEvents',
displayEventTime: true,
eventRender: function(event, element, view) {
if (event.allDay === 'true') {
event.allDay = true;
} else {
event.allDay = false;
}
},
});
calendar.render();
I have specified the route correctly in this script as events: 'getEvents', you can see that at the end part of the above script.
Now the result in the frontend is:
There is no data displayed from the DB.
And I am getting a console error as: Failed to load resource: the server responded with a status of 404 (Not Found): http://127.0.0.1:8000/getEvents?start=2021-09-26T00%3A00%3A00%2B05%3A30&end=2021-11-07T00%3A00%3A00%2B05%3A30
As you can see there are some unwanted characters in the URL obtained.
The debugging is not working here, I do not know why.. when I add dd($data) or something other there is no debugger part in Frontend.
Please help me to solve this thing.
Thank you.
It is worked. All I was done is correct. The issue was with my route, Due to one function to redirect invalid routes to the 404 page, My route to the controller was not working..
When I put the 404 route to the bottom of all other routes, It is worked.

Failure parsing JSON error with Laravel 6 and Fullcalendar 4

I have the following script in the blade.php:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var SITEURL = "{{url('/dash')}}";
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'bootstrap', 'interaction', 'dayGrid', 'timeGrid'],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,'
},
themeSystem: 'bootstrap',
editable: true,
navLinks: true,
events: SITEURL + "/calendar",
displayEventTime: true,
defaultView: 'timeGridWeek',
selectable: true,
selectHelper: true,
eventRender: function (event, element, view) {
if (event.allDay === 'true') {
event.allDay = true;
} else {
event.allDay = false;
}
},
And in the controller this part which is get the events from the database:
public function index(Request $request)
{
if(request()->ajax()) {
$returnedColumns = ['id', 'title', 'start', 'end'];
$start = (!empty($request->start)) ? ($request->start) : ('');
$end = (!empty($request->end)) ? ($request->end) : ('');
$events = Event::whereBetween('start', [$start, $end])->get($returnedColumns);
return response()->json($events);
}
return view('/dash/calendar');
}
The Json looks like this, if I remove the if(request()->ajax()) { part:
[{"id":347,"title":"Unavailable","start":"2020-02-11 06:00:00","end":"2020-02-11 06:30:00"}]
Seems the request working fine, but I got JSON parse error, and the calendar just won't show the events. What could be a problem?

ember model find query with params doesn't display on pagination

2I have an Ember app which connects to an api from where it gets articles. I make use of pagination to get 10 articles per request. This works. But now I wanted to add sorting to the request. I implemented this by using the extra parameter in the store.find.
However, for some reason if I use the 'return this.store.find('article', params);' instead of 'return this.store.find('article');' new articles (still requested and added correctly to the store!) in the getMore function are not beiing displayed or rendered. But when i remove the params parameter from store.find in model, it does work. What could be the case here?
templates/articles.hbs
<script type="text/x-handlebars" data-template-name="articles">
{{#each itemController="article"}}
<div class="item">
//...
</div>
{{/each}}
</script>
routes/articles.js
import Ember from 'ember';
export default Ember.Route.extend(Ember.UserApp.ProtectedRouteMixin, {
model: function(params) {
var params2 = {page: 1, per_page: 10, sort: params.sort};
return this.store.find('article', params2);
},
setupController: function(controller, model) {
controller.set('content', model);
},
actions:{
//...
},
getMore: function() {
// don't load new data if we already are
//if (this.get('loadingMore')) return;
//this.set('loadingMore', true);
var meta = this.store.metadataFor("article");
if (meta.hasmore) {
var controller = this.get('controller'),
nextPage = controller.get('page') + 1,
perPage = controller.get('perPage'),
sorting = controller.get('sort'),
items;
var params = {page: nextPage, per_page: perPage, sort: sorting};
this.store.findQuery('article', params).then(function (articles) {
controller.set('page', controller.get('page') + 1);
//this.set('loadingMore', false);
});
}
else{
$('#pagination_spinner').hide();
}
},
queryParamsDidChange: function() {
this.refresh();
}
}
});
controllers/articles.js
import Ember from 'ember';
var ArticlesController = Ember.ArrayController.extend({
itemController: 'article',
queryParams: ['sort'],
sort: 'rating',
page: 1,
perPage: 10
});
export default ArticlesController;
views/articles.js
import Ember from 'ember';
export default Ember.View.extend({
didInsertElement: function(){
//this.scheduleMasonry();
this.applyMasonry();
// we want to make sure 'this' inside `didScroll` refers
// to the IndexView, so we use jquery's `proxy` method to bind it
//this.applyMasonry();
$(window).on('scroll', $.proxy(this.didScroll, this));
},
willDestroyElement: function(){
this.destroyMasonry();
// have to use the same argument to `off` that we did to `on`
$(window).off('scroll', $.proxy(this.didScroll, this));
},
// this is called every time we scroll
didScroll: function(){
if (this.isScrolledToBottom()) {
$('#pagination_spinner').addClass('active');
this.get('controller').send('getMore');
}
},
scheduleMasonry: (function(){
Ember.run.scheduleOnce('afterRender', this, this.applyMasonry);
}).observes('controller.model.#each'), //TODO check
applyMasonry: function(){
$('#pagination_spinner').removeClass('active');
var $galleryContainer = $('#galleryContainer');
$galleryContainer.imagesLoaded(function() {
// check if masonry is initialized
var msnry = $galleryContainer.data('masonry');
if ( msnry ) {
msnry.reloadItems();
// disable transition
var transitionDuration = msnry.options.transitionDuration;
msnry.options.transitionDuration = 0;
msnry.layout();
// reset transition
msnry.options.transitionDuration = transitionDuration;
} else {
// init masonry
$galleryContainer.masonry({
itemSelector: '.item',
columnWidth: 0,
"isFitWidth": true
});
}
});
},
destroyMasonry: function(){
$('#galleryContainer').masonry('destroy');
},
// we check if we are at the bottom of the page
isScrolledToBottom: function(){
var distanceToViewportTop = (
$(document).height() - $(window).height());
var viewPortTop = $(document).scrollTop();
if (viewPortTop === 0) {
// if we are at the top of the page, don't do
// the infinite scroll thing
return false;
}
return (viewPortTop - distanceToViewportTop === 0);
}
});
nothing smart coming to my mind, but maybe it's that...
You've got the line:
if (meta.hasmore) {
in your getMore() function. Is this the case that you've got this meta field in one response and forgot in the other?

backbone collection add does not trigger model validate

I am rather new to backbone and wanted to test a simple script that handles a to do list. Here is the code i used so far:
(function() {
window.App = {
Models: {},
Collections: {},
Views: {}
};
window.template = function(id) {
return _.template($('#' + id).html());
}
App.Models.Task = Backbone.Model.extend({
validate: function(attributes) {
if ( !$.trim(attributes.title) ) {
return 'Invalid title';
}
}
});
App.Collections.Tasks = Backbone.Collection.extend({
model: App.Models.Task
});
App.Views.Task = Backbone.View.extend({
tagName: 'li',
template: template('taskTemplate'),
initialize: function () {
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
},
events: {
'click .edit': 'editTask',
'click .delete': 'destroy'
},
destroy: function() {
if (confirm('Are you sure?')) {
this.model.destroy();
}
},
remove: function() {
this.$el.remove();
},
editTask: function() {
var newTaskTitle = prompt('New title:', this.model.get('title'));
this.model.set('title', newTaskTitle, {validate: true});
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
App.Views.AddTask = Backbone.View.extend({
el: 'form#addTask',
initialize: function() {
},
events: {
'submit': 'submit'
},
submit: function(event) {
event.preventDefault();
var newTaskTitle = $(event.currentTarget).find('input[type=text]').val();
var task = new App.Models.Task({ title: newTaskTitle });
this.collection.add(task, {add: true, merge: false, remove: false});
}
});
App.Views.Tasks = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
this.collection.on('add', this.addOne, this);
},
render: function() {
this.collection.each(this.addOne, this);
return this;
},
addOne: function(task) {
var taskView = new App.Views.Task({ model: task });
this.$el.append(taskView.render().el);
}
});
var tasks = new App.Collections.Tasks([
{
title: 'Go to store',
priority: 4
},
{
title: 'Go to mall',
priority: 3
},
{
title: 'Get to work',
priority: 5
}
]);
var addTaskView = new App.Views.AddTask({ collection: tasks });
var tasksView = new App.Views.Tasks({ collection: tasks });
$('div.tasks').append(tasksView.render().el);
})();
So the model validation works fine ... the only pb is that collection.add does not validate the newly added model .... is the a way to force the validation?
Thanks,
Rares
From the fine manual:
validate model.validate(attributes, options)
[...] By default validate is called before save, but can also be
called before set if {validate:true} is passed.
Collection#add does not call save nor does it call set with the validate: true option. If you want to validate during add, say so:
collection.add(models, { validate: true });
That will get validate:true all that way down to Model#set.
A quick look at a simplified example may be helpful:
var M = Backbone.Model.extend({
set: function() {
console.log('setting...');
Backbone.Model.prototype.set.apply(this, arguments);
},
validate: function() {
console.log('validating...');
return 'Never!';
}
});
var C = Backbone.Collection.extend({
model: M
});
var c = new C;
c.on('add', function() {
console.log('Added: ', arguments);
});
c.on('invalid', function() {
console.log('Error: ', arguments);
});
Now if we do this (http://jsfiddle.net/ambiguous/7NqPg/):
c.add(
{ where: 'is', pancakes: 'house?' },
{ validate: true }
);
You'll see that set is called with validate: true, validate will be called, and you'll get an error. But if you say this (http://jsfiddle.net/ambiguous/7b2mn/):
c.add(
{ where: 'is', pancakes: 'house?' },
{add: true, merge: false, remove: false} // Your options
);
You'll see that set is called without validate: true, validate will not be called, and the model will be added to the collection.
The above behavior is quite strongly implied but not explicitly specified so you may not want to trust it. Model#initialize does say:
you can pass in the initial values of the attributes, which will be set on the model.
and set does explicitly mention the validate option. However, there is no guarantee that Collection#add will send options to the model constructor or set or that the model's constructor will send the options to set. So if you want to be really paranoid and future proof, you could add a quick check for this "options get all the way down to set" behavior to your test suite; then, if it changes you'll know about it and you can fix it.
if you pass options to your collection add method, the validation method will not be called and as your arguments in this case are all set to the default value, there is not need to pass them
this.collection.add(task);
you may want to take a look at this question.
Prevent Backbone.js model from validating when first added to collection

ember ajax calls with promisses access result in templates and controller

I'm making a call to the server to get some data via an ajax request and I use a promise. While my template automatically updates as soon as the data is returned, I'm unlucky accessing the data in the controller, as I don't know exactly when it's there.
To resolve I can make an additional ajax call in the controller to get the same data but that feels ugly. Is there a nicer way to know when to access the data in the controller? As a work around I tried to call the function that needs the data on the didInsertElement but that didn't solve it.
App.ActiveDataSet = Ember.Object.extend({
progress: 0
});
App.ActiveDataSet.reopenClass({
findAll: function(project_id) {
var result = [];
$.ajax({
url: '/active_data_sets.json',
type: 'GET',
data: {'project_id': project_id}
}).then(function(response) {
response.active_data_sets.forEach(function(newset) {
result.addObject(App.ActiveDataSet.create(newset));
});
});
return result;
}
});
App.MapviewShowRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor('activedatasetIndex').set('content', App.ActiveDataSet.findAll(model.id));
}
});
App.MapviewShowController = Ember.ObjectController.extend({
needs: ['activedatasetIndex'],
content: null,
dataSets: [],
createDataSets: function() {
// create the datasets
for (var counter = 0; counter < this.get('controllers.activedatasetIndex.content').length; counter++) {
alert(dataSets[counter].ds.name);
}
}
});
App.MapviewShowView = Ember.View.extend({
map: null,
didInsertElement: function() {
var map = null;
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(52.368892, 4.875183),
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(this.$('#map_canvas').get(0), myOptions);
this.set('map', map); //save for future updations
var h = $(window).height(),
offsetTop = 60; // Calculate the top offset
$('#map_canvas').css('height', (h - offsetTop));
// get the datasets
this.controller.createDataSets();
}
});
Have you tried continuing the promises chain:
App.ActiveDataSet.reopenClass({
findAll: function(project_id) {
return $.ajax({
url: '/active_data_sets.json',
type: 'GET',
data: {'project_id': project_id}
}).then(function(response) {
var result = [];
response.active_data_sets.forEach(function(newset) {
result.addObject(App.ActiveDataSet.create(newset));
});
return result;
});
}
});
App.MapviewShowRoute = Ember.Route.extend({
setupController: function(controller, model) {
App.ActiveDataSet.findAll(model.id).then(function(content) {
this.controllerFor('activedatasetIndex').set('content', content);
});
}
});

Resources