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