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 } }; }