Events disapearing after month change - angularjs

I've been using the ui-calendar for an application. But, today I've got a problem that when I change the month (for example, click the button and go from February to March and after this I go back) my events gone.
When I load:
When I Change:
When I Go Back:
The code config I've been using this time.
`
$scope.alertOnEventClick = function(date, jsEvent, view) {
console.log('evento clicado', date, jsEvent, view);
}
$scope.eventRender = function( event, element, view ) {
element.attr({'tooltip': event.title, 'tooltip-append-to-body': true});
$compile(element)($scope);
};
$scope.changeView = function(view,calendar) {
uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
};
$scope.renderCalender = function(calendar) {
if(uiCalendarConfig.calendars[calendar]){
uiCalendarConfig.calendars[calendar].fullCalendar('render');
}
};
$scope.eventSources = [$scope.events];
$scope.uiConfig = {
calendar:{
lang: 'pt-br',
height: "parent",
editable: false,
theme:true,
header:{
left: '',
center: 'title',
right: 'today, prev,next'
},
eventClick: $scope.alertOnEventClick,
eventRender: $scope.eventRender
}
};
`

It's an issue in ui-calendar. I've found a solution where I change the function onAdded to:
eventsWatcher.onAdded = function (event) {
if (calendar && calendar.fullCalendar) {
calendar.fullCalendar('renderEvent', event, true);
}
};

Related

ui-calendar one event per day

I am using ui-calendar with angularjs in my project for a leave management project.If a user has taken a leave on some day ,i want to restrict him from selecting that date again.ie if a user has taken a leave on 23rd JUNE 2017,and when the user selects dates from 21st JUNE 2017 to 24th JUNE 2017 using ui-calendar select multiple option,i should get an alert saying there is a leave already taken .How to go about this .Please help.
Info:
I am fetching leave events from my database using REST Webservices.
I am using fullcalendar.js file which says the version is v2.4.0
My code
app.factory('calendarSer', ['$http', '$rootScope', 'uiCalendarConfig', function($http, $rootScope, uiCalendarConfig) {
return {
displayCalendar: function($scope) {
$http.get("rest/leave/holidayList", {}).success(function(data, status, headers, config) {
$scope.holidayList = data;
$calendar = $('[ui-calendar]');
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
$scope.changeView = function(view) {
$calendar.fullCalendar('changeView', view);
};
var m = null;
if ($scope.selectable == "Yes") {
m = true;
} else {
m = false;
}
/* config object */
$scope.uiConfig = {
calendar: {
lang: 'da',
height: 400,
editable: true,
selectable: m,
displayEventTime: false,
header: {
left: 'month basicWeek basicDay',
center: 'title',
right: 'today prev,next'
},
eventClick: function(date, jsEvent, view) {
$scope.alertMessage = (date.title + ' was clicked ');
alert("clicked" + date.title);
},
select: function(start, end, allDay) {
if(start < new Date())
{
alert("You cannot apply for leave on this day")
}
else
{
// Its a right date
// Do something
var obj = {};
obj.startDate = start.toDate();
obj.endDate = end.toDate();
$rootScope.selectionDate = obj;
$("#modal1").openModal();
}
},
dayRender: function(date, cell) {
var today = new Date();
today = moment(today).toDate();
var end = new Date();
end = moment(end).toDate();
end.setDate(today.getDate() + 7);
date = moment(date).toDate();
angular.forEach($scope.holidayList, function(value) {
if (((moment(value.holiday_date).format("YYYY-MM-DD")) == moment(date).format("YYYY-MM-DD"))) {
cell.css("background-color", "#2bbbad");
//$('.date').text('Today');
// cell.prepend("<span style=\"max-width:200px;word-wrap:break-word;margin-top:10px;\">" + value.description + "</span>");
// cell.prepend("<br>")
}
});
},
eventRender: $scope.eventRender,
}
};
console.log($scope.holidayList);
}).error(function(data, status, headers, config) {
alert("error from holidaylist");
});
$scope.events = [];
$scope.eventSources = [$scope.events];
$http.get($scope.url, {
cache: true,
params: {signum:$scope.signum}
}).then(function(data) {
console.log(data);
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function(value) {
console.log(value.title);
if (value.approvalStatus == "Approved") {
var k = '#114727';
} else {
k = '#b20000'
}
$scope.events.push({
title: value.signum,
description: value.signum,
start: value.startDate,
end: value.endDate,
allDay: value.isHalfDay,
stick: true,
status: value.approvalStatus,
backgroundColor: k
});
});
});
}
}
}]);
In the "select" callback, get the list of existing events, and if any of them have dates which overlap the selection, then it means the user has already got leave booked for all or part of the selection. So you can stop it from continuing just like you already have got when checking that it's before today's date (p.s. you should use momentJS's date comparison functions for more robust results - see momentjs.com/docs/#/query). Also, when you submit the data to the server, the server should validate this rule again, since client-side data can always be manipulated by a malicious user.
To get the events, you wouldn't get them from the DB - use this: https://fullcalendar.io/docs/event_data/clientEvents to get the events currently showing in the calendar. You can use the filter callback to return only ones that will be relevant to your selected start/end dates

ui-calendar cell background color not displaying for the first time

I am trying to get a list of dates from Rest and change the background color of those dates using dayRender .But when i try to do it the color is not getting changed for the first time.If i go to next month and come back to the month,it will work perfectly.Here are screenshots to make it more clear.
When i load the page
When i move from june to july
When move back to june
Here is my code .rest/leave/holidayList is the rest url for retreiving dates from db.
app.factory('calendarSer', ['$http', '$rootScope', 'uiCalendarConfig', function($http, $rootScope, uiCalendarConfig) {
return {
displayCalendar: function($scope) {
$http.get("rest/leave/holidayList", {}).success(function(data, status, headers, config) {
$scope.holidayList = data;
console.log($scope.holidayList);
}).error(function(data, status, headers, config) {
alert("error");
});
$calendar = $('[ui-calendar]');
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
$scope.changeView = function(view) {
$calendar.fullCalendar('changeView', view);
};
var m = null;
if ($scope.selectable == "Yes") {
m = true;
} else {
m = false;
}
/* config object */
$scope.uiConfig = {
calendar: {
lang: 'da',
height: 400,
editable: true,
selectable: m,
header: {
left: 'month basicWeek basicDay',
center: 'title',
right: 'today prev,next'
},
eventClick: function(date, jsEvent, view) {
$scope.alertMessage = (date.title + ' was clicked ');
alert("clicked" + date.title);
},
select: function(start, end, allDay) {
var obj = {};
obj.startDate = start.toDate();
obj.endDate=moment(end - 1 * 24 * 3600 * 1000).format('YYYY-MM-DD');
$rootScope.selectionDate = obj;
$("#modal1").openModal();
// calendar.fullCalendar('unselect');
},
dayRender: function (date, cell) {
var today = new Date();
today=moment(today).toDate();
var end = new Date();
end=moment(end).toDate();
end.setDate(today.getDate()+7);
date=moment(date).toDate();
angular.forEach($scope.holidayList,function(value){
if(((moment(value.holiday_date).format("YYYY-MM-DD"))==moment(date).format("YYYY-MM-DD")))
{
cell.css("background-color", "red");
}
});
},
eventRender: $scope.eventRender,
}
};
$scope.events = [];
$scope.eventSources = [$scope.events];
$http.get($scope.url, {
cache: true,
params: {}
}).then(function(data) {
console.log(data);
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function(value) {
console.log(value.title);
if (value.approvalStatus == "Approved") {
var k = '#114727';
} else {
k = '#b20000'
}
$scope.events.push({
title: value.signum,
description: value.signum,
start: value.startDate,
end: value.endDate,
allDay: value.isHalfDay,
stick: true,
status: value.approvalStatus,
backgroundColor: k
});
});
});
}
}
}]);
Remember that the REST call is asynchronous. Just put all the code that set colours inside a promise, so when the REST service rest/leave/holidayList responses, then you paint the colours. You can use nested promises if needed.
Here's some code:
$http.get('rest/leave/holidayList').then(function(response) {
// success
$scope.holidayList = data;
/* config object */
$scope.uiConfig = {
calendar: {
/* calendar code */
}
}
}, function(response) {
// error handler
});
To compare the use of "success" and "then" have a look at:
https://stackoverflow.com/a/16385350/8058079

Add Right Click Event to Full calender Angular JS Api

I am using the Angular UI Calender API in my MVC Project
UI Calender API [http://angular-ui.github.io/ui-calendar/]
I want to add right click Context Menu to it.On clicking any date or Event the context Menu should appear containing link options
1.Add Appointment
2.Add Meeting
3.Add Task
I have used the Bootstrap Context Menu https://github.com/Templarian/ui.bootstrap.contextMenu
The Problem I am facing is on right click the context menu is appearing the event does not captures the Date and Event details from the Calender which i need to pass to show in a POP UP.
I have used below code in my Angular Js Controller.
var calendarDemoApp = angular.module('myCalendarApp', ['ui.calendar', 'ui.bootstrap', 'ui.bootstrap.contextMenu']);
calendarDemoApp.controller('CalendarCtrl',
function ($scope, $http,$compile, $timeout, uiCalendarConfig) {
$scope.SelectedEvent = null;
var isFirstTime = true;`enter code here`
$scope.events = [];
$scope.eventSources = [$scope.events];
//Load events from server
$http.get('/home/getevents', {
cache: true,
params: {}
}).then(function (data) {
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function (value) {
$scope.events.push({
title: value.Title,
description: value.Description,
start: new Date(parseInt(value.StartAt.substr(6))),
end: new Date(parseInt(value.EndAt.substr(6))),
allDay: value.IsFullDay,
stick: true
});
});
});
/* alert on eventClick */
$scope.alertOnEventClick = function (date, jsEvent, view) {
$scope.alertMessage = (date.title + ' was clicked ');
};
/* alert on Drop */
$scope.alertOnDrop = function (event, delta, revertFunc, jsEvent, ui, view) {
$scope.alertMessage = ('Event Dropped to make dayDelta ' + delta);
};
/* alert on Resize */
$scope.alertOnResize = function (event, delta, revertFunc, jsEvent, ui, view) {
$scope.alertMessage = ('Event Resized to make dayDelta ' + delta);
};
/* add and removes an event source of choice */
$scope.addRemoveEventSource = function (sources, source) {
var canAdd = 0;
angular.forEach(sources, function (value, key) {
if (sources[key] === source) {
sources.splice(key, 1);
canAdd = 1;
}
});
if (canAdd === 0) {
sources.push(source);
}
};
/* add custom event*/
$scope.addEvent = function () {
};
/* remove event */
$scope.remove = function (index) {
$scope.events.splice(index, 1);
};
/* Change View */
$scope.changeView = function (view, calendar) {
uiCalendarConfig.calendars[calendar].fullCalendar('changeView', view);
};
/* Change View */
$scope.renderCalendar = function (calendar) {
$timeout(function () {
if (uiCalendarConfig.calendars[calendar]) {
uiCalendarConfig.calendars[calendar].fullCalendar('render');
}
});
};
/*COntext Menu*/
var AppointmentHtml = '<div style="cursor: pointer;"><i class="glyphicon glyphicon-plus"></i>New Appointment</div>';
var AppointmentItem = {
html: AppointmentHtml, click: function ($itemScope, event, modelValue, text, $li, date, jsEvent, view) {
debugger;
var winH = $(window).height();
var winW = $(window).width();
$.ajax({
url: '/Home/Appointment',
data: {},
cache: false,
success: function (result) {
//alert(result);
$("#dialog-content").html(result);
$("#divEdit").dialog({
modal: true,
title: 'Add Appointment',
close: function (event, ui) {
$(this).dialog('destroy');
}
});
$(".ui-dialog").css({ 'min-width': '600px', 'left': winW / 2 - 300 });
},
error: function (request, status, error) {
alert(status);
}
});
}
};
var MeetingHtml = '<div style="cursor: pointer;"><i class="glyphicon glyphicon-user"></i>New Meeting</div>';
var MeetingItem = {
html: MeetingHtml, click: function ($itemScope, event, modelValue, text, $li) {
alert("New Appointment");
console.info($itemScope);
console.info(event);
console.info(modelValue);
console.info(text);
console.info($li);
}
};
var TaskHtml = '<div style="cursor: pointer;"><i class="glyphicon glyphicon-tasks"></i>New Task</div>';
var TaskItem = {
html: TaskHtml, click: function ($itemScope, event, modelValue, text, $li) {
alert("New Task");
console.info($itemScope);
console.info(event);
console.info(modelValue);
console.info(text);
console.info($li);
}
};
$scope.customHTMLOptions = [AppointmentItem, MeetingItem,
TaskItem
];
/* Render Tooltip */
$scope.eventRender = function (event, element, view) {
element.attr({
'tooltip': event.title,
'tooltip-append-to-body': true
});
$compile(element)($scope);
};
/* config object */
$scope.uiConfig = {
calendar: {
height: 450,
editable: true,
header: {
left: 'title',
center: '',
right: 'today prev,next'
},
eventClick: function (event) {
$scope.SelectedEvent = event;
},
eventDrop: $scope.alertOnDrop,
eventResize: $scope.alertOnResize,
eventRender: $scope.eventRender,
eventAfterAllRender: function () {
if ($scope.events.length > 0 && isFirstTime) {
//Focus first event
uiCalendarConfig.calendars.myCalendar.fullCalendar('gotoDate', $scope.events[0].start);
isFirstTime = false;
}
}
}
};
$scope.changeLang = function () {
if ($scope.changeTo === 'Hungarian') {
$scope.uiConfig.calendar.dayNames = ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat"];
$scope.uiConfig.calendar.dayNamesShort = ["Vas", "Hét", "Kedd", "Sze", "Csüt", "Pén", "Szo"];
$scope.changeTo = 'English';
} else {
$scope.uiConfig.calendar.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
$scope.uiConfig.calendar.dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
$scope.changeTo = 'Hungarian';
}
};
/* event sources array*/
//$scope.eventSources = [$scope.events, $scope.eventSource, $scope.eventsF];
//$scope.eventSources2 = [$scope.calEventsExt, $scope.eventsF, $scope.events];
});
Below is my HTML Code:
<section id="directives-calendar" ng-controller="CalendarCtrl">
<div class="calendar" ng-model="eventSources" calendar="myCalendar" context-menu="customHTMLOptions" config="uiConfig.calendar" ui-calendar="uiConfig.calendar"></div>
</Section>

Angular ui calendar, $scope.events remains as undefined

here's what my controllers looks like
var resource = Restangular.all('api/events/');
resource.getList().then(function(events){
$scope.events = events;
});
$scope.eventRender = function( event, element, view ) {
element.attr({'tooltip': event.title,
'tooltip-append-to-body': true});
$compile(element)($scope);
};
/* config object */
$scope.uiConfig = {
calendar:{
height: 700,
editable: true,
header: {
left: 'prev,next title',
//center: 'title',
right: 'month,agendaWeek,'
},
eventRender: $scope.eventRender
}
};
/* event sources array*/
$scope.eventSources = [$scope.events];
i think angular ui calendar directive is getting triggered first,
how can i make it to get data first and then trigger directive?
You can specify a function in eventSources which does the fetching like so, you have to call the callback function with an array of events.
var resource = Restangular.all('api/events/');
/* event sources array*/
$scope.eventSources = [fetchEvents];
function fetchEvents(start, end, timezone, callback) {
resource.getList()
.then(function(events) {
// do some event processing ?
callback(events);
});
}
Side note from my own experience with fullCalendar and Angular:
$scope.eventRender = function( event, element, view ) {
element.attr({'tooltip': event.title, 'tooltip-append-to-body': true});
$compile(element)($scope);
};
This is a really big bottleneck on performance, and you probably want to avoid this. It will create a dom node+logic for EVERY event you render, which can be quite a lot. The best thing to do is to either make your own tooltip directive which reuses the same dom element or to use the title attribute.
Please try this it should work
/* config object */
$scope.uiConfig = {
calendar:{
height: 700,
editable: true,
header: {
left: 'prev,next title',
//center: 'title',
right: 'month,agendaWeek,'
},
eventRender: getEvents
}
};
$scope.eventSources = [];
function getEvents(callback){
console.log(from); // For test purposes
// Request for data from server and when it comes, call callback to update calendar
var resource = Restangular.all('api/events/');
resource.getList().then(function(events){
$scope.events = events;
callback(events);
});
}
};

What is the correct way to use ui-calendar with Urigo's angular-meteor?

I want to use ui-calendar with Urigo's angular-meteor. I code like this, it doesn't work but I don't know why and how to fix it.
The collection is not empty but event do not appear in calendar. Thank you for attention.
https://github.com/wuxianliang/ui-calendar-angular-meteor
CalEvents = new Mongo.Collection("calevents");
CalEvents.allow({
insert: function () {
return true;
},
update: function () {
return true;
},
remove: function () {
return true;
}
});
if (Meteor.isClient) {
angular.module('Calendardemo', ['angular-meteor', 'ui.calendar','ui.router', 'angularMoment','mgcrea.ngStrap','ngAnimate']);
Meteor.startup(function() {
angular.bootstrap(document, ['Calendardemo']);
});
angular.module('Calendardemo').controller('MyCalendar', [
'$scope',
'$collection',
function($scope, $collection) {
$collection(CalEvents).bind($scope,'calevents',true,true);
$scope.addCalEvent=function(date, jsEvent, view){
var startDateTime = moment(date).format('YYYY-MM-DDTHH:mm:ss.SSSZ');
var endDateTime = moment(date).add(1, 'h').format('YYYY-MM-DDTHH:mm:ss.SSSZ');
$scope.calevents.push({
title: 'New Event',
start: startDateTime,
end: endDateTime,
completed: null,
doing: null
})
};
$scope.eventRender = function(event,element){};
/* config object */
$scope.uiConfig = {
calendar:{
height: 450,
defaultView: 'month',
lang: 'en',
eventColor: 'grey',
header:{
left: 'prev next today',
center: 'title',
right: 'month agendaWeek'
},
dayClick: $scope.addCalEvent,
eventRender: $scope.eventRender,
editable: true,
selectable: true,
allDayDefault: false
}
};
$scope.eventSources = [$scope.calevents];
}]);}
if (Meteor.isServer) {
Meteor.publish('calevents', function(){
return CalEvents.find();
})
}
You should use this package:
https://github.com/netanelgilad/meteor-angular-ui-calendar
This package wraps angular-ui-calendar for Meteor.
It might not updated so you can open an issue inside
EDIT
You might also want to check out this package that looks more updated:
https://atmospherejs.com/planettraining/angular-ui-calendar

Resources