Regarding displaying ui-calendar events - angularjs

Hello all i am designing a leave management website with angularjs and ui-calendar.If a user takes a leave ,the values are taken from the database and displayed as an event in the calendar.Now what i want to do is ,if the user is not absent on particular day,it should be displayed as present event.Hope the following image helps understanding better.
Now vikki is taking leave on friday.I want to mark other dates as an event displaying in different color saying he s present.I need this to be in the week view.Please let me know if there is any way to do this thing.Following is my code
app.factory('calendarSer', ['$http','$rootScope', 'uiCalendarConfig', function ($http,$rootScope, uiCalendarConfig) {
return {
displayCalendar: function($scope) {
$calendar = $('[ui-calendar]');
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
$scope.changeView = function(view) {
$calendar.fullCalendar('changeView', view);
};
/* config object */
$scope.uiConfig = {
calendar: {
lang: 'da',
height: 450,
editable: true,
selectable: true,
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.startAt = start.toDate();
obj.startAt = new Date(obj.startAt).toUTCString();
obj.startAt = obj.startAt.split(' ').slice(0, 4).join(' ');
obj.endAt = end.toDate();
obj.endAt = new Date(obj.endAt).toUTCString();
obj.endAt = obj.endAt.split(' ').slice(0, 4).join(' ');
$rootScope.selectionDate = obj;
$("#modal1").openModal();
calendar.fullCalendar('unselect');
},
eventRender: $scope.eventRender
}
};
$scope.events = [];
$scope.eventSources = [$scope.events];
$http.get("rest/leave/list", {
cache: true,
params: {}
}).then(function(data) {
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function(value) {
console.log(value.title);
$scope.events.push({
title: value.title,
description: value.description,
start: value.startAt,
end: value.endAt,
allDay: value.isFull,
stick: true
});
});
});
}
}
}]);
Thanking you

You need to also create the events array which would display the user is present. However, if you try to create the array in the front-end, then you would not know the other user information to fill the calendar.
"rest/leave/list" : will return that vikki is on leave, however what if the other user that has not taken any leave and is not returned in this array? how will you be able to fill the calendar saying user is present all the other days?
$scope.events.push({
title: value.title,
description: value.description,
start: value.startAt,
end: value.endAt,
allDay: value.isFull,
stick: true
});
$scope.eventSources = [$scope.events];
You are filling the events and binding it to the eventSources.
So you need to return something like below from the reponse "rest/leave/list":
{
title: "vikki",
description: "description",
startAt: "2017-05-05 00:00",
endAt: "2017-05-05 23:59",
isFull: true,
leave: true <- This will say he is absent
},
{
title: "vikki",
description: "description",
//The start and end date time will control the block that will be booked in the calendar
startAt: "2017-06-05 00:00",
endAt: "2017-01-06 23:59",
isFull: true,
leave: false <- This will say he is present
//This array will book the calendar from May-06 to end of the month.
//If you want the past, then create one in the past and send it from
//server
}
In the above array, you need to create separate rows for absent and present. For example , 1st row consist of January month where the user has not taken any leaves, so you create a row with Start date Jan 01 and End date Jan 30, In Feb, the user has taken one leave on say 5th. So you create three rows, row 1 with Feb 01 to Feb 04 as present, row 2 with Feb 05 as absent, and row 3 with Feb 06 - Feb 31 as present
Using the variable "leave" from the array, in the frontend you can change the colour. You can refer it from this how to achieve it.
Jquery Full calendar and dynamic event colors

Related

Dynamically mark dates in react-native-calendars

I'am trying to mark dates in react-native-calendars that i get from an api call. Can someone please help?
<Calendar
markingType={'multi-dot'}
markedDates={this.state.dates}
/>
In constructor, I am maintaining
this.state = {dates : []}
I have invoked the function marked() where I am mapping over the data and pushing the dates into another array and then doing a setState as
this.setState({
dates : {
[attendance] : [
{
key: 'vacation',
color: 'blue',
selectedDotColor: 'red'
}
]
}
})
I'am sharing the code I am at liberty to.
P.S : I'am new to this.
Thanks in andvance
please use this library it's easy to customization with custom date styles "react-native-calendar-picker"
Make sure that markedDates param is immutable. If you change markedDates object content but the reference to it does not change calendar update will not be triggered.
Please try;
markedDates={{
'2019-12-9': {
periods: [
{ startingDay: false, endingDay: true, color: '#5f9ea0' },
{ startingDay: false, endingDay: true, color: '#ffa500' },
{ startingDay: true, endingDay: false, color: '#f0e68c' },
]
},
'2019-12-9': {
periods: [
{ startingDay: true, endingDay: false, color: '#ffa500' },
{ color: 'transparent' },
{ startingDay: false, endingDay: false, color: '#f0e68c' },
]
},
}}
I actually had to do the exact same thing recently with react-native-calendars. Here is a simplified version of the function I wrote to create marked dates:
createMarkedDates = (dates) => {
let markedEvents = {};
let numEvents = {};
let uniqueDates = [...new Set(dates)]; //remove duplicate event dates
dates.forEach(function (count) { //if multiple events on one date, determine how many events are on each date
numEvents[count] = (numEvents[count] || 0) + 1;
});
uniqueDates.forEach(function (date) {
let dots = [];
let markedData = {};
for (let i = 0; i < numEvents[date]; i++) {
dots.push(event); //add dots for as many events are on that day
}
markedData['dots'] = dots; //set the array of dots
markedEvents[date] = markedData; //add markers to marked dates
});
};
this.setState({markedDates: markedEvents});
}
dates is an array of dates that is being passed from the API.
This should output you a marked date object with the markings for each date, and also if you need it, it will put multiple dots on a day if it appears more than once in your array.
Also, I believe your dates need to be in ISO date format (YYYY-MM-DD) for react-native-calendars to mark the dates.
I hope this example helps!

Load data dynamically when I change the date

This is my calendar object
$scope.uiConfig = {
calendar: {
height: 450,
editable: false,
header: {
left: 'title',
center: '',
right: 'today prev,next'
},
eventClick: $scope.onEventClick,
eventDrop: $scope.alertOnDrop,
eventResize: $scope.alertOnResize,
eventRender: $scope.eventRender,
dayClick: $scope.onDayClick,
viewRender: $scope.getData
}
};
and
$scope.getData = function(view, element){
$scope.intervalStartDate = new Date(view.start);
$scope.intervalEndDate = new Date(view.end);
$scope.managedEvents = Event.getFittingsForDateInterval({
intervalStartDate : convertDate($scope.intervalStartDate),
intervalEndDate : convertDate($scope.intervalEndDate)
});
$scope.managedEvents.$promise.then(function(data){
$scope.uiConfig.calendar.events = data;
});
}
if I remove
$scope.uiConfig.calendar.events = data;
no data is populating and if i include that it is refreshing and loading current month data
for the first time it is loading the data for January month, whenever I click on next month icon, it is calling for February month data and again calendar is resetting to present month (it is calling $scope.getData again)
data = [{start : some_date, end : some_date, title : event_name},{start : some_date, end : some_date, title : event_name},{start : some_date, end : some_date, title : event_name},{start : some_date, end : some_date, title : event_name},{start : some_date, end : some_date, title : event_name}];
I want to get data for only current view instead of all at once.
any help would be appreciated.
Controller.js Code: .
$scope.getEvents = function(){
var obj = {};
$scope.events = [];
obj.startDate = new Date($scope.myView.intervalStart).getTime();
obj.endDate = new Date($scope.myView.intervalEnd).getTime();
if($scope.myView.name == "month"){
obj.endDate = obj.endDate - 19801000;
}
//Give a call to database from here, in which obj contains
// start and end of the view
var getEventsPromise = masterCalendarAPI.getEvents(obj);
getEventsPromise.then(function (response) {
if(response.statusCode == 200){
//Assign $scope.event the list object retrieved from database
}
},
function (error) {
console.log(error);
});
}
//Remember this method will be called on each view change with all details in 'view' object
$scope.renderView = function (view) {
$scope.myView = view;
$scope.getEvents();
}
$scope.uiConfig = {
calendar: {
height: 500,
editable: false,
header: {
left: 'prev,next title',
center: '',
right: 'month,agendaWeek,agendaDay'
},
eventLimit: true,
views: {
month: {
eventLimit:3
}
},
columnFormat:'dddd',
timezone: 'local',
timeFormat: 'hh:mm a',
titleFormat:'MMMM D, YYYY',
slotDuration:'00:30:00',
eventRender:$scope.eventRender,
eventClick: $scope.eventClicked,
dayClick: $scope.dayClick,
eventDrop: $scope.alertOnDrop,
eventResize: $scope.alertOnResize,
viewRender: $scope.renderView
}
} ;
//event sources array
$scope.eventSources = [$scope.events];

resizing an event in fullcalendar

I'm working with a fullCalendar and I want to get the "end" property value for an event after resizing it like this:
for this first event "gaming day"
I get start = Mon Aug 01 2016 01:00:00 GMT+0100 (WEST) and
end = Wed Aug 02 2016 01:00:00 GMT+0100 (WEST)
how can I get the the value of end after resizing my event manually
this is my code :
$scope.listEvents = [{
title: 'Gaming Day',
start: '2016-08-13T12:00:00',
end: '2016-08-15T00:00:00',
color: #9b59b6,
allDay: true
}, {
title: 'Live Conference',
start: new Date(y, m, 3)
}, {
title: 'Top Secret Project',
start: new Date(y, m, 4),
end: new Date(y, m, 8),
color: '#1abc9c'
}];
$('#calendar').fullCalendar({
header: {
left: 'prev,next',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
firstDay: 1,
editable: true,
droppable: true,
drop: function(date, allDay) { // this function is called when something is dropped
// retrieve the dropped element's stored Event Object
var originalEventObject = $(this).data('eventObject');
// we need to copy it, so that multiple events don't have a reference to the same object
var copiedEventObject = $.extend({}, originalEventObject);
// assign it the date that was reported
copiedEventObject.start = date;
// render the event on the calendar
// the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
$('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
// remove the element from the "Draggable Events" list
$(this).remove();
},
events: $scope.listEvents,
eventDrop: function(event, delta, revertFunc) {
/* After a drag and drop of my event I get the new position with this */
console.log(event.title);
if (event.start) console.log(event.start._d);
if (event.end) console.log(event.end._d);
}
});
So after resizing the event how can I get the new end date?
Use the eventResize property:
function eventResize(event, delta, revertFunc) {
var endDate = event.end.format().toString();
var startDate = event.start.format().toString();
}
And in the calendar config add the reference to the function:
header: {...},
eventResize: eventResize

How Can I add Dynamic Textboxes in extjs grid

I am having a button on page on the click of the button i need to add rows inside extjs grid.
The row will contain the controls like textbox, combobox, datefields etc.
I have added dynamic rows to the store like this -
var r = Ext.create('Model', {
name: 'XYZ',
email: 'abc#abc.com',
start: new Date(),
salary: 50000,
active: true
});
var i = 0;
page.store.insert(i, r);
But this way i can add records only. and i want to add controls to the grid. Please suggest.
Thanks,
I have used the grid row editing plugin for the issue.
Here i am adding the row to the store and opening it in edit mode via edit plugin.
Sample code is here.
tbar: [
{
text: 'Add Row',
iconCls: 'employee-add',
handler: function () {
//var Date = new Date();
//var Time = new Date().getTime() / 1000;
rowEditing.cancelEdit();
// Create a model instance
var r = Ext.create('TagAdjustment', {
startDate: Ext.Date.clearTime(new Date()),
startTime: 10,
stopDate: Ext.Date.clearTime(new Date()),
stopTime: 10,
rampStart: 10,
rampStop: 10,
gen: 10
});
var selectedRecord = grid.getSelectionModel().getSelection()[0];
var row = grid.store.indexOf(selectedRecord);
store.insert(row + 1, r);
rowEditing.startEdit(row + 1, 0);
}
},

Extjs grid grouping summary click event

I'm using Ext.grid.Panel with Ext.grid.feature.GroupingSummary. i need to add listener for summary row click event. Is there are any event for summary row click.
Ext.create('Ext.grid.Panel', {
features:[
Ext.create('Ext.grid.feature.GroupingSummary',{
ftype: 'groupingsummary'
})
],
As far as I can tell, there's nothing built-in to do that. You will have to catch the click event on the summary element yourself. That remains relatively easy. Things get complicated if you need to know the group of the summary that has been clicked...
You can use the getGroupName method of the feature. For that, you'll need to keep a reference to the grouping feature instance and, the joyful part, you'll have to find the group header element that matches the clicked summary element. To spice things up even a little more, the markup for group and summary elements seems to have changed drastically in Ext 4.2.
Here's the code of a listener (on the click event of summary element) which does all that.
function(e, target) {
// Find group element (header), for the clicked summary
var groupEl;
if (Ext.getVersion().isLessThan('4.2')) {
// Life used to be easy with everything being a row
// in the table (actual rows, group headers,
// summary row)...
groupEl = Ext.fly(target).prev('.x-grid-group-hd');
} else {
// But from Ext4.2, everything became complicated.
// Group headers & summary row seem to be embedded
// in the next or previous regular row... Since I
// haven't entirely understood the logic behind, I
// cannot guarantee this will work with all possible
// cases...
var row = Ext.fly(target).up('.x-grid-row');
while (row && !groupEl) {
groupEl = row.down('.x-grid-group-hd');
row = row.prev('.x-grid-row');
}
}
// We can get the group name from the group element,
// but we need a reference to the grouping feature
// instance...
var groupName = groupingSummary.getGroupName(groupEl);
// Here you are...
console.log('Group clicked: ' + groupName);
}
And here's a complete example, based on the grouping summary grid example from the doc.
Ext.define('TestResult', {
extend: 'Ext.data.Model',
fields: ['student', 'subject', {
name: 'mark',
type: 'int'
}]
});
var groupingSummary = Ext.create('Ext.grid.feature.GroupingSummary', {
groupHeaderTpl: 'Subject: {name}',
ftype: 'groupingsummary'
});
Ext.create('Ext.grid.Panel', {
width: 200,
height: 240,
renderTo: document.body,
features: [groupingSummary],
store: {
model: 'TestResult',
groupField: 'subject',
data: [{
student: 'Student 1',
subject: 'Math',
mark: 84
},{
student: 'Student 1',
subject: 'Science',
mark: 72
},{
student: 'Student 2',
subject: 'Math',
mark: 96
},{
student: 'Student 2',
subject: 'Science',
mark: 68
}]
},
columns: [{
dataIndex: 'student',
text: 'Name',
summaryType: 'count',
summaryRenderer: function(value){
return Ext.String.format('{0} student{1}', value, value !== 1 ? 's' : '');
}
}, {
dataIndex: 'mark',
text: 'Mark',
summaryType: 'average'
}]
,listeners: {
click: {
element: 'body'
,delegate: '.x-grid-row-summary'
,fn: function(e, target) {
// Find group element (header), for the clicked summary
var groupEl;
if (Ext.getVersion().isLessThan('4.2')) {
// Life used to be easy with everything being a row
// in the table (actual rows, group headers,
// summary row)...
groupEl = Ext.fly(target).prev('.x-grid-group-hd');
} else {
// But from Ext4.2, everything became complicated.
// Group headers & summary row seem to be embedded
// in the next or previous regular row... Since I
// haven't entirely understood the logic behind, I
// cannot guarantee this will work with all possible
// cases...
var row = Ext.fly(target).up('.x-grid-row');
while (row && !groupEl) {
groupEl = row.down('.x-grid-group-hd');
row = row.prev('.x-grid-row');
}
}
// We can get the group name from the group element,
// but we need a reference to the grouping feature
// instance...
var groupName = groupingSummary.getGroupName(groupEl);
// Here you are...
console.log('Group clicked: ' + groupName);
}
}
}
});
The goal of this answer is just to demonstrate the principles. You may want to organize this code in a better way... The cleanest would probably be to extend or override the GroupingSummary class.

Resources