FullCalendar Jquery Plugin’i Asp.Net MVC Projesinde Nasıl Kullanırız ?

Jquery plugin’lerinin neredeyse hepsini şu an yürütmekte olduğum proje için kullanmaktayım. Yeni başlamış olduğum bu seride, pluginleri kullanırkende anlatmayı amaçlamaktayım. İlk yazıma bana en yakın gelen takvim uygulaması ile başlamak istedim.

Öncelikle Visual studio IDE’mizde bir Empty ama MVC template’te bir proje başlatıyoruz.

Projenin başlatılması için izlenecek yol
Visual studi’da file->new->project ve ardından Asp.Net Web Application(.Net Framework) seçerek bu ekrana ulaşıyoruz.

Projemiz açılır açılmaz bir mdf dosyası ekliyoruz. Bunun için App_Data klasörüne gelip add-> new item sekmelerini seçiyoruz ve açılan pencerede sol menude bulunan data sekmesini seçiyoruz. Ve Projemize bir adet Sql Server DataBase ekliyoruz. Aşağıdaki Resimde bunu anlatmaya çalıştım.
SWl Server DataBase'in Projeye eklenmesi.

SQL Server veritabanımızı projemize ekledikten sonra bu veritabanına bir planların tutulacağı bir tablo eklemesi yapıyoruz. Üst menüde bulunan View sekmesinden Server Explorer menüsünü açıyoruz.Burada eklediğimiz veritabanını incelediğimizde Tables sekmesini görürürüz ve yine sağ tıklayarak yeni bir tablo oluştur diyerek planlarımızı koyacağımız tabloyu oluşturmaya başlıyoruz.
Swl Server veritabanına yeni tablo eklenmesi.

Event tablosu için gereken sütunların oluşturulmasına dair sql dilinin kullanımı ve sonuç aşağıdaki resimdedir. Resme bakarak sizde tablonuzu oluşturabilirsiniz.
Events tablosunun oluşturulması

Tablomuz hazır olduğuna göre projemize yeni bir controller ve controller içinde gelen ındex methoduna bir tane view ekliyoruz. Bu adımları daha önceki makalelerimde bahsettiğim için geçiyorum.Bu adımları gerçekleştiremezseniz lütfen yorum atın ilgileneyim.

Veritabanımıza tablomuzu oluşturup controller ve view’imizi de oluşturduktan sonra, veritabanında bulunan tablomuza erişebilmek için ADO.NET Entity Model ekliyoruz. Diğer ekleme işlemlerinde de yaptığımız gibi, ekleme yapmak istediğimiz model klasörü üzerine gelip sağ tıklayıp add new item diyerek, sol menüde DATA sekmesi altında bulunan ADO.NET Entity Model’i seçiyoruz. Bu adımı daha iyi anlayabilmek adına, bilginiz yoksa, bu adımın öncesinde ADO.NET Entity Model hakkında kısa da olsa bilgi edinmenizi öneririm.

Ado.Net Entity Model'in Projeye Dahil Edilmesi

Controller’ımızı açıyoruz ve Veritabanında bulunan planları get ve save edecek olan metotlarımızı yazmaya başlıyoruz.Bu kodları, kod üzerinde yorum ile açıklamaya çalıştım. Sorularınız olursa lütfen yorum bırakınız.
Veritabanından Veri Okunması

[HttpGet]//httpget diyerek methodumuz ne iş yapacağını belirtiyoruz.
public JsonResult GetEvents() { //Jquery ile planlarımızı takvim üzerine yerleştireceğiz
//bu nedenle JSonResult değer döndürüyoruz
using (DBCalendarEntities dc = new DBCalendarEntities())//Eklediğimiz entitymodel'dan bir örnek alıyoruz
{
var events = dc.Tbl_Events.ToList(); //bütün tabloyu select ediyoruz.Bu nedenle ayrıca select yazmıyorum.
//tabloda birden fazla değer olabilir o nedenle firstOrdefault yerine ToList diyorum
return new JsonResult { Data = events, JsonRequestBehavior=JsonRequestBehavior.AllowGet};
//Son olarak methodun döndürdüğü verinin Json Datası olduğunu söylüyor ve Data niteliğine events diyorum.
}
}

Veritabanına Plan Kaydedilmesi ve Güncellenmesi

[HttpPost]//httpost diyerek methodun kayıt işi yapacağını belirtiyoruz.
public JsonResult SaveEvent(Tbl_Events e) //Sonucu yine Json döndürüyoruz
{
var status = false;//Yapılan işlemin başarısını status değişkeninde tutuyorm
using (DBCalendarEntities dc =new DBCalendarEntities()){//Yine bir örnek alıyorum model'ımdan
if(e.EventID > 0)//eğer kaydetmek istediğim planın id değeri 0 dan büyükse
{
//Güncelleme yap diyorum. Bunun içinde bu planı tablomda bulup v değişkenine atıyorum.
var v = dc.Tbl_Events.Where(a=>a.EventID==e.EventID).FirstOrDefault();
if (v != null)//v değerinin null olup olmadığını kontrol ediyorum
{//ve sırasıyla parametre olarak gelen plan değerlerini, veritabanındaki değerlerle değiştiriyorum
v.Subject = e.Subject;
v.Description = e.Description;
v.Start = e.Start;
v.End = e.End;
v.IsFullDay = e.IsFullDay;
v.ThemeColor = e.ThemeColor;
}
}
else
{//eğer EbentID değeri 0 dan büyük değilse bu yeni kayıt olduğu anlamına gelir
//ve doğrudan tabloma eklerim
dc.Tbl_Events.Add(e);
}
dc.SaveChanges();//yapılan değişimin veritabanına yanstılması için
status = true;//işlem başarıyla tamamlandığı için status değişkeni true ile set edilir.
}
return new JsonResult { Data = new { status=status } };//status değişkenini view'e gönderirim

}

Plan Silme Methodu

[HttpPost]//httpost diyerek methodun kayıt işi yapacağını belirtiyoruz.
public JsonResult DeleteEvent(int EventID) //Sonucu yine Json döndürüyoruz
{
//method parametre olarak silinecek olan planın id değerini alıyor
var status = false;
using (DBCalendarEntities dc = new DBCalendarEntities())//Yine bir örnek alıyorum model'ımdan
{
//id değerini kullanarak silinecek olan planı veritabında arayıp buluyorum.
var v=dc.Tbl_Events.Where(a => a.EventID == EventID).FirstOrDefault();

if (v != null)//bulunan değer null değilse
{
dc.Tbl_Events.Remove(v);//veritabanından kaldırıyorum
dc.SaveChanges();//yapılan değişimin veritabanına yanstılması için
status = true;//işlem başarıyla tamamlandığı için status değişkeni true ile set edilir.
}

}
return new JsonResult { Data=new { status = status } };//status değişkenini view'e gönderirim
}

Controller’da method tanımlamalarımız ardından Index View’imizi açıyoruz. Öncelikle sayfamıza FullCalendar için gereken css ve js uzantılı dosyaların linkini vermekle işe başlıyoruz.

@section Scripts{
https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js
//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js

Server tarafındaki verileri client tarafında kullanmamız ve göstermemiz için gereken javascript kodları aşağıdaki gibidir.

$(document).ready(function () { //Tüm Dom ağacı yüklendikten sonra çalışmaya başlanacak olan kodlar
var events = [];//planlarımı ekleyeceğim bir array oluşturuyorum
var selectedEvent = null;// tıkladığım planı tutacak olan değişken
PlanGetirYukleCalendar();//Devamlı bir yenilemeye ihtiyaç duyulacağı için fonksiyon yazıldı
function PlanGetirYukleCalendar() {
events = []; //yine planları tutacak bir arrayimiz var
$.ajax({ //planlarımız server taradından geleceği için ajax'tan yardım alıyoruz'
type: "GET", //çağtılan methodumuzun ne iş yaptığı
url: "/home/GetEvents",//controller/method
success: function (data) {//server çağrısı başarılı olursa
$.each(data, function (i, v) {
events.push({//arrayime sırasıyla çektiğim verileri atıyorum niteliklerine uygun olarak
eventID: v.EventID,
title: v.Subject,
description: v.Description,
start: moment(v.Start),
end: v.End != null ? moment(v.End) : null,
color: v.ThemeColor,
allDay: v.IsFullDay
});
})

TakvimOlustur(events);//Tüm planların çekimini yaptıktan sorna takvimi oluşturmak için fonksiyonumu çağırıyorum
},
error: function (error) {//server cevabı hatalı olursa alert verdiriyorum.
alert('Hata');
}
})
}

function TakvimOlustur(events) {
$('#calender').fullCalendar('destroy'); //var olan takbimi önce bir yok ediyorum
$('#calender').fullCalendar({
contentHeight: 400,//takvim için yükseklik veriyorum
defaultDate: new Date(),//varsayılan olarak bugünü göster diyorum
timeFormat: 'h(:mm)a',//format belirliyoruz
header: {//başlık kısmında bvulunması istediğim butonlar ve yerleri
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay,agenda'
},
eventLimit: true,
eventColor: '#378006',
events: events,
eventClick: function (calEvent, jsEvent, view) { //plana tıklanınca olacak olaylar
selectedEvent = calEvent;//tıklanan planı tutuyorum
$('#clndrModal #eventTitle').text(calEvent.title); //ve ilk bilgilendirme modal'ımı çağırıyorum'
var $description = $('

');
$description.append($('

').html('Başlangıç:' + calEvent.start.format("DD-MMM-YYYY HH:mm a")));
if (calEvent.end != null) {
$description.append($('

').html('Bitim:' + calEvent.end.format("DD-MMM-YYYY HH:mm a")));
}
$description.append($('

').html('Açıklama:' + calEvent.description));
$('#clndrModal #pDetails').empty().html($description); //Modal üzerine, planımın niteliklerini yerleştiriyorum

$('#clndrModal').modal(); //modalıma açıl diyorum
},
selectable: true, //planın seçilebilirliğini true yapıyorum
select: function (start, end) {
selectedEvent = { //seçilen plana dair varsayılan değerleri set'liyorum'
eventID: 0,
title: '',
description: '',
start: start,
end: end,
allDay: false,
color: ''
};
openAddEditForm();//düzenleme formunu aç diyorum
$('#calendar').fullCalendar('unselect'); //seçilmiş durumdaki takvimi seçilmemiş hale getriiyorum
},
editable: true,//Planın duzenlenebilirliğini true yapıyorum
eventDrop: function (event) { //Planın silinmesi durumundaçalışacak olan method
var data = {
EventID: event.eventID,
Subject: event.title,
Start: event.start.format('DD/MM/YYYY HH:mm A'),
End: event.end != null ? event.end.format('DD/MM/YYYY HH:mm A') : null,
Description: event.description,
ThemeColor: event.color,
IsFullDay: event.allDay
};
SaveEvent(data);
}
})
}

$('#btnEdit').click(function () {
//Düzenleme olayı için gereken modal açılır
openAddEditForm();
})
$('#btnDelete').click(function () {//sil butonuna tıklanınca confirm alert çıkarıyoruz
if (selectedEvent != null && confirm('Emin Misin?')) {
$.ajax({
type: "POST", //ajax ile silinecek olan planın id değerini method'a parametre veriyoruz'
url: '/home/DeleteEvent',//controller/method
data: { 'eventID': selectedEvent.eventID },//seçilen planın id değerini parametre verrim
success: function (data) {
if (data.status) { //controllerdan bize status Verisinin geldiğini hatırlayın
PlanGetirYukleCalendar();
$('#clndrModal').modal('hide');//Silme durumunun ardından bu modalı kapatıyoruz
}
},
error: function () {//status verisi false gelirse
alert('Hata');
}
})
}
})
$('#dtp1,#dtp2').datetimepicker({//Plan oluşumunda kullanılacak olan bootstrap'ın datetimepickerları
format: 'DD/MM/YYYY HH:mm A'
});
$('#chkIsFullDay').change(function () {//tam gün planı ise bitiş zamanına dair bootstrap datetimepicker saklanır
if ($(this).is(':checked')) {
$('#divEndDate').hide();
}
else {
$('#divEndDate').show();
}
});
//düzenleme işlemi için form açıldığında
//açılan formun düzenlenecek olan planın değerleriyle dolu olarak gelmesi için
//Jquery val ile niteliğin değeri alındı ve set edildi form inputlarına
function openAddEditForm() {
if (selectedEvent != null) {
$('#hdEventID').val(selectedEvent.eventID);
$('#txtSubject').val(selectedEvent.title);
$('#txtStart').val(selectedEvent.start.format('DD/MM/YYYY HH:mm A'));
$('#chkIsFullDay').prop("checked", selectedEvent.allDay || false);
$('#chkIsFullDay').change();
$('#txtEnd').val(selectedEvent.end != null ? selectedEvent.end.format('DD/MM/YYYY HH:mm A') : '');
$('#txtDescription').val(selectedEvent.description);
$('#ddThemeColor').val(selectedEvent.color);
}
$('#clndrModal').modal('hide');
$('#clndrModalSave').modal();
}
//Kaydet butonuna basıldığında Form inputlarını kontrol ederim oncelıkle
$('#btnSave').click(function () {
//Doğrulama
if ($('#txtSubject').val().trim() == "") {
alert('Konu Boş Bırakılamaz.');
return;
}
if ($('#txtStart').val().trim() == "") {
alert('Başlangıç Zamanı Boş Bırakılamaz');
return;
}
if ($('#chkIsFullDay').is(':checked') == false && $('#txtEnd').val().trim() == "") {
alert('Bitim Zamanı Boş Bırakılamaz');
return;
}
else {
var startDate = moment($('#txtStart').val(), "DD/MM/YYYY HH:mm A").toDate();
var endDate = moment($('#txtEnd').val(), "DD/MM/YYYY HH:mm A").toDate();
if (startDate > endDate) {
alert('Bitim Zamanı Başlangıç Zamanından Önce Olamaz.');
return;
}
}
//Controller kısmına pass edilecek veri Json formatta toparlanır
var data = {
EventID: $('#hdEventID').val(),
Subject: $('#txtSubject').val().trim(),
Start: $('#txtStart').val().trim(),
End: $('#chkIsFullDay').is(':checked') ? null : $('#txtEnd').val().trim(),
Description: $('#txtDescription').val(),
ThemeColor: $('#ddThemeColor').val(),
IsFullDay: $('#chkIsFullDay').is(':checked')
}
// Server kısmına data'yı pass etmek için fonksıyonumu çağırırım'
SaveEvent(data);

})
function SaveEvent(data) {
$.ajax({
type: "POST",//ajax ile silinecek olan planın id değerini method'a parametre veriyoruz'
url: '/home/SaveEvent',////controller/method
data: data,//post edilecek data
success: function (data) {
if (data.status) { //controllerdan bize status Verisinin geldiğini hatırlayın
//Takvimi yenile
PlanGetirYukleCalendar();
$('#clndrModalSave').modal('hide');//Katdet modalımızı kapatıyoru<.
}
},
error: function () {
alert('Hata');
}
})
}
})

Beklenen çıktılar şu şekilde olmalıdır

Takvimin Genel Görünümü

Bilgilendirme Modalının görünümü.
Bu modalın açılabilmesi için plana tıklamak gerektiğini unutmayın.

Düzenleme modalının görünümü.

Silme butonunun çalışması

Yeni Bir Plan Eklemesi
Yeni bir plan eklemek için, ekleme yapacağımız güne tıklmamamız gerekir.

Diğer bir pluginin kullanım örneğinde görüşmek üzere.

Nisanur Bulut

Yorum bırakın