Introduction
In the previous article, I have shown Implement Event/Scheduler calendar using ui-calendar in angularJS, where we have only implemented a simple scheduling application for showing events using ui-calendar (fullcalender). But without CRUD operation, it can not be a complete solution. So, Today I will show you complete CRUD operation on fullcalender with AngularJS for complete the application so It can be useful.Before starting must read Implement Event/Scheduler calendar using ui-calendar in angularJS first.
Read more articles using AngularJS with ASP.NET.
Just follow the following steps in order to implement "Part 2 - CRUD operation on fullcalender with angularJS".
Step - 13: Update View (HTML) for getting bootstrap modal dialog for CRUD operation.
When user will select calendar time slot by clicking or dragging, the user will get a modal popup for add new events and when will click on any existing events they will get a modal popup for edit/delete that event.
Open your view (here Index.cshtml from Solution Explorer > Views > Index.cshtml) and update the yellow marked lines.
Complete View (HTML) :
@{
ViewBag.Title = "Index";
}
<h2>Event/Scheduler calendar using ui-calendar in AngularJS </h2>
@* HTML *@
<div ng-app="myApp" ng-controller="myNgController">
<script type="text/ng-template" id="modalContent.html">
<div class="modal-header">
<h3 class="modal-title">Events</h3>
</div>
<div class="modal-body">
<div class="error">{{Message}}</div>
<div class="form-group">
<label>Event Title :</label>
<input type="text" ng-model="NewEvent.Title" autofocus class="form-control" required />
</div>
<div class="form-group">
<label>Description :</label>
<textarea ng-model="NewEvent.Description" autofocus class="form-control"></textarea>
</div>
<div class="form-group">
<label>Time Slot :</label>
<span>
{{NewEvent.StartAt}} - {{NewEvent.EndAt}}
</span>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">Save</button>
<button class="btn btn-danger" type="button" ng-show="NewEvent.EventID > 0" ng-click="delete()">Delete </button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<div class="row">
<div class="col-md-12">
<div id="calendar" ui-calendar="uiConfig.calendar" ng-model="eventSources" calendar="myCalendar"></div>
</div>
@*<div class="col-md-4">
<div ng-show="SelectedEvent" class="alert alert-success" style="margin-top:50px">
<h2 style="margin-top:0px"> Selected Event:</h2>
<h3 style="color:#A9A50E">{{SelectedEvent.title}}</h3>
<p>{{SelectedEvent.description}}</p>
</div>
</div>*@
</div>
</div>
@* CSS *@
<link href="~/Content/fullcalendar.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
@* JS *@
<script src="~/Scripts/moment.js"></script>
<script src="~/Scripts/jquery-1.11.3.js"></script>
@*<script src="~/Scripts/angular.js"></script>*@
@* Will use latest angularjs *@
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
<script src="~/Scripts/calendar.js"></script>
<script src="~/Scripts/fullcalendar.js"></script>
<script src="~/Scripts/gcal.js"></script>
@* OUR ANGULAR COMPONENTs *@
<script src="~/Scripts/MyApp.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script>
<style>
.error{
color:red;
}
</style>
line 8 to line 34, here I have added a ng-template for modal dialog content.
line 58 added a script tag for angular library 1.5.0
line 65 added a script "ui-bootstrap-tpls.min.js" for modal popup
line 66 to line 70 added for add a CSS class for styling error message
Step - 14: Update MyApp.js with followings
Here we will do followings (yellow marked)...
2. Add a function for clear events from calendar (line 22 - line 27)
3. Add a function for show events to calendar from database (added existing code for fetch data into this populate function) (line 31 - line 51)
4. Configure ui-calendar for select event by clicking or dragging for add events (line 57 - line 97)
5. Add an angular controller for implement bootstrap modal (line 160 - line 177)
6. Add a function for show modal dialog for CURD operation (line 121 - line 155)
var app = angular.module('myApp', ['ui.calendar','ui.bootstrap']); // added u.bootstrap for modal dialog
app.controller('myNgController', ['$scope', '$http', 'uiCalendarConfig', '$uibModal', function ($scope, $http, uiCalendarConfig, $uibModal) {
$scope.SelectedEvent = null;
var isFirstTime = true;
$scope.events = [];
$scope.eventSources = [$scope.events];
$scope.NewEvent = {};
//this function for get datetime from json date
function getDate(datetime) {
if (datetime != null) {
var mili = datetime.replace(/\/Date\((-?\d+)\)\//, '$1');
return new Date(parseInt(mili));
}
else {
return "";
}
}
// this function for clear clender enents
function clearCalendar() {
if (uiCalendarConfig.calendars.myCalendar != null) {
uiCalendarConfig.calendars.myCalendar.fullCalendar('removeEvents');
uiCalendarConfig.calendars.myCalendar.fullCalendar('unselect');
}
}
// will put this to a method
//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
});
});
});
function populate() {
clearCalendar();
$http.get('/home/getevents', {
cache: false,
params: {}
}).then(function (data) {
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function (value) {
$scope.events.push({
id : value.EventID,
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
});
});
});
}
populate();
//configure calendar
$scope.uiConfig = {
calendar: {
height: 450,
editable: true,
displayEventTime: true,
header: {
left: 'month,agendaWeek,agendaDay',
center: 'title',
right:'today prev,next'
},
timeFormat : {
month : ' ', // for hide on month view
agenda: 'h:mm t'
},
selectable: true,
selectHelper: true,
select : function(start, end){
var fromDate = moment(start).format('YYYY/MM/DD LT');
var endDate = moment(end).format('YYYY/MM/DD LT');
$scope.NewEvent = {
EventID : 0,
StartAt : fromDate,
EndAt : endDate,
IsFullDay :false,
Title : '',
Description : ''
}
$scope.ShowModal();
},
eventClick: function (event) {
$scope.SelectedEvent = event;
var fromDate = moment(event.start).format('YYYY/MM/DD LT');
var endDate = moment(event.end).format('YYYY/MM/DD LT');
$scope.NewEvent = {
EventID : event.id,
StartAt : fromDate,
EndAt : endDate,
IsFullDay :false,
Title : event.title,
Description : event.description
}
$scope.ShowModal();
},
eventAfterAllRender: function () {
if ($scope.events.length > 0 && isFirstTime) {
//Focus first event
uiCalendarConfig.calendars.myCalendar.fullCalendar('gotoDate', $scope.events[0].start);
isFirstTime = false;
}
}
}
};
//This function for show modal dialog
$scope.ShowModal = function () {
$scope.option = {
templateUrl: 'modalContent.html',
controller: 'modalController',
backdrop: 'static',
resolve: {
NewEvent: function () {
return $scope.NewEvent;
}
}
};
var modal = $uibModal.open($scope.option);
modal.result.then(function (data) {
$scope.NewEvent = data.event;
switch (data.operation) {
case 'Save':
//Save here
$http({
method: 'POST',
url: '/home/SaveEvent',
data : $scope.NewEvent
}).then(function (response) {
if (response.data.status) {
populate();
}
})
break;
case 'Delete':
//Delete here $http({
$http({
method: 'POST',
url: '/home/DeleteEvent',
data: {'eventID' : $scope.NewEvent.EventID }
}).then(function (response) {
if (response.data.status) {
populate();
}
})
break;
default:
break;
}
}, function () {
console.log('Modal dialog closed');
})
}
}])
// create a new controller for modal
app.controller('modalController', ['$scope', '$uibModalInstance', 'NewEvent', function ($scope, $uibModalInstance,NewEvent) {
$scope.NewEvent = NewEvent;
$scope.Message = "";
$scope.ok = function () {
if ($scope.NewEvent.Title.trim() != "") {
$uibModalInstance.close({event : $scope.NewEvent, operation: 'Save'});
}
else {
$scope.Message = "Event title required!";
}
}
$scope.delete = function () {
$uibModalInstance.close({ event: $scope.NewEvent, operation: 'Delete' });
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
}
}])
Step-15: Add new action into your MVC controller for saving Event.
//Action for Save event
[HttpPost]
public JsonResult SaveEvent(Event evt)
{
bool status = false;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
if (evt.EndAt != null && evt.StartAt.TimeOfDay == new TimeSpan(0,0,0) &&
evt.EndAt.Value.TimeOfDay == new TimeSpan(0,0,0))
{
evt.IsFullDay = true;
}
else
{
evt.IsFullDay = false;
}
if (evt.EventID > 0)
{
var v = dc.Events.Where(a => a.EventID.Equals(evt.EventID)).FirstOrDefault();
if (v != null)
{
v.Title = evt.Title;
v.Description = evt.Description;
v.StartAt = evt.StartAt;
v.EndAt = evt.EndAt;
v.IsFullDay = evt.IsFullDay;
}
}
else
{
dc.Events.Add(evt);
}
dc.SaveChanges();
status = true;
}
return new JsonResult { Data = new { status = status} };
}
Step-16: Add an another action in our MVC controller for delete Event from the database.
[HttpPost]
public JsonResult DeleteEvent(int eventID)
{
bool status = false;
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
var v = dc.Events.Where(a => a.EventID.Equals(eventID)).FirstOrDefault();
if (v != null)
{
dc.Events.Remove(v);
dc.SaveChanges();
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}