FullCalendar – jQuery Event Calendar in ASP.NET

东方旭东
2023-12-01

https://github.com/esausilva/ASP.Net-EventCalendar

http://trentrichardson.com/examples/timepicker/

https://github.com/posabsolute/jQuery-Validation-Engine

https://github.com/xdan/datetimepicker

Libraries


sql:

create table CalendarEvent
(
    event_id INT IDENTITY(1,1) PRIMARY KEY,
    [description] NVARCHAR(100),
    title NVARCHAR(100),
    event_start DATETIME,
    event_end DATETIME,
    all_day BIT DEFAULT(0)
);
GO

fullCalendarTimepicker.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="fullCalendarTimepicker.aspx.cs" Inherits="fullcalendardemo.fullCalendarTimepicker" %>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>ASP.NET FullCalendar</title>
    <link href="ajax/libs/jqueryui/1.12.1/themes/cupertino/jquery-ui.min.css" rel="stylesheet" />
    <link href="ajax/libs/fullcalendar/3.1.1/fullcalendar.min.css" rel="stylesheet" />
    <link href="ajax/libs/qtip2/3.0.3/jquery.qtip.min.css" rel="stylesheet" />   
    <link rel="stylesheet" media="all" type="text/css" href="ajax/libs/timepicker/jquery-ui-timepicker-addon.css" /> 
    <link rel="stylesheet" href="ajax/libs/formValidator/css/validationEngine.jquery.css" type="text/css"  media="screen" charset="utf-8" />

    <style type='text/css'>
        body
        {
            margin-top: 40px;
            text-align: center;
            font-size: 14px;
            font-family: "Lucida Grande" ,Helvetica,Arial,Verdana,sans-serif;
        }
        #calendar
        {
            width: 900px;
            margin: 0 auto;
        }
        /* css for timepicker */
        .ui-timepicker-div dl
        {
            text-align: left;
        }
        .ui-timepicker-div dl dt
        {
            height: 25px;
        }
        .ui-timepicker-div dl dd
        {
            margin: -25px 0 10px 65px;
        }
        .style1
        {
            width: 100%;
        }
        
        /* table fields alignment*/
        .alignRight
        {
        	text-align:right;
        	padding-right:10px;
        	padding-bottom:10px;
        }
        .alignLeft
        {
        	text-align:left;
        	padding-bottom:10px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
    </asp:ScriptManager>
    <div id="calendar">
    </div>
    <div id="updatedialog" style="font: 70% 'Trebuchet MS', sans-serif; margin: 50px;display: none;"
        title="Update or Delete Event">
        <table class="style1">
            <tr>
                <td class="alignRight">
                    Name:</td>
                <td class="alignLeft">
                    <input id="eventName" type="text" size="33" /><br /></td>
            </tr>
            <tr>
                <td class="alignRight">
                    Description:</td>
                <td class="alignLeft">
                    <textarea id="eventDesc" cols="30" rows="3" ></textarea></td>
            </tr>
            <tr>
                <td class="alignRight">
                    Start:</td>
                <td class="alignLeft">
                    <input id="eventStart"  name="eventStart" value="" /></td>
            </tr>
            <tr>
                <td class="alignRight">
                    End: </td>
                <td class="alignLeft">
                    <input id="eventEnd" name="eventEnd" value=""/><input type="hidden" id="eventId" /></td>
            </tr>
        </table>
    </div>
    <div id="addDialog" style="font: 70% 'Trebuchet MS', sans-serif; margin: 50px;" title="Add Event">
    <table class="style1">
            <tr>
                <td class="alignRight">
                    Name:</td>
                <td class="alignLeft">
                    <input id="addEventName" type="text" size="33" /><br /></td>
            </tr>
            <tr>
                <td class="alignRight">
                    Description:</td>
                <td class="alignLeft">
                    <textarea id="addEventDesc" cols="30" rows="3" ></textarea></td>
            </tr>
            <tr>
                <td class="alignRight">
                    Start:</td>
                <td class="alignLeft">
                    <input id="addEventStartDate" class="validate[required,funcCall[validate2time]]" name="addEventStartDate" value=""/></td>
            </tr>
            <tr>
                <td class="alignRight">
                    End:</td>
                <td class="alignLeft">
                    <input id="addEventEndDate" class="validate[required,funcCall[validate2time]]" name="addEventEndDate" value=""/></td>
            </tr>
        </table>
        
    </div>
    <div runat="server" id="jsonDiv" />
    <input type="hidden" id="hdClient" runat="server" />
    </form>

    <script src="ajax/libs/moment.js/2.18.1/moment.min.js" type="text/javascript"></script>
    <script src="ajax/libs/jquery/3.1.1/jquery.min.js" type="text/javascript"></script>
    <script src="ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script>
    <script src="ajax/libs/qtip2/3.0.3/jquery.qtip.min.js" type="text/javascript"></script>
     <script type="text/javascript" src="ajax/libs/timepicker/jquery-ui-timepicker-addon.js"></script>
     <script type="text/javascript" src="ajax/libs/timepicker/i18n/jquery-ui-timepicker-addon-i18n.min.js"></script>
     <script type="text/javascript" src="ajax/libs/timepicker/i18n/jquery-ui-timepicker-zh-CN.js"></script>
     <script type="text/javascript" src="ajax/libs/timepicker/jquery-ui-sliderAccess.js"></script>
    <script src="ajax/libs/fullcalendar/3.1.1/fullcalendar.min.js" type="text/javascript"></script>
    <script src='ajax/libs/fullcalendar/3.1.1/locale-all.js' type="text/javascript"></script>
        <script src="ajax/libs/formValidator/js/jquery.validationEngine.js" type="text/javascript"></script>
     <script src="ajax/libs/formValidator/js/languages/jquery.validationEngine-zh_CN.js" type="text/javascript"></script>  
     <script src="ajax/libs/jqueryui/1.12.1/ui/i18n/datepicker-zh-CN.js" type="text/javascript"></script>
    <script src="scripts/calendarscriptTime.js" type="text/javascript"></script>
</body>
</html>

calendarscriptTime.js:


var currentUpdateEvent;
var addStartDate;
var addEndDate;
var globalAllDay;

//修改時,穫取值
// 涂聚文 Geovin Du edit 20170417
function updateEvent(event, element) {
    //alert(event.description);

    if ($(this).data("qtip")) $(this).qtip("destroy");

    currentUpdateEvent = event;

    $('#updatedialog').dialog('open');
    $("#eventName").val(event.title);
    $("#eventDesc").val(event.description);
    $("#eventId").val(event.id);
    $("#eventStart").val("" + $.fullCalendar.formatDate(event.start, "YYYY-MM-DD HH:mm")); //text $.fullCalendar.formatDate(event.start, "YYYY-MM-DD HH:mm")
    $("#eventStart").datetimepicker({ timeInput: true, changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd', timeFormat: 'HH:mm', hourMin: 5, hourMax: 24, hourGrid: 3, minuteGrid: 15 }); //timeInput: true,
    //$("#eventStart").datetimepicker('setDate', (new Date())); 
    if (event.end === null) {
        $("#eventEnd").val(""); //text
    }
    else {
        $("#eventEnd").val("" + $.fullCalendar.formatDate(event.end, "YYYY-MM-DD HH:mm")); //text  event.end.toLocaleString()
        $("#eventEnd").datetimepicker({ timeInput: true, changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd', timeFormat: 'HH:mm', hourMin: 5, hourMax: 24, hourGrid: 3, minuteGrid: 15 }); //
    }

    return false;
}

function updateSuccess(updateResult) {
    //alert(updateResult);
}

function deleteSuccess(deleteResult) {
    //alert(deleteResult);
}

function addSuccess(addResult) {
    // if addresult is -1, means event was not added
    //    alert("added key: " + addResult);

    if (addResult != -1) {
        $('#calendar').fullCalendar('renderEvent',
						{
						    title: $("#addEventName").val(),
						    start: addStartDate,
						    end: addEndDate,
						    id: addResult,
						    description: $("#addEventDesc").val(),
						    allDay: globalAllDay
						},
						true // make the event "stick"
					);


        $('#calendar').fullCalendar('unselect');
    }
}

function UpdateTimeSuccess(updateResult) {
    //alert(updateResult);
}
//
$("#addEventStartDate").datetimepicker({
        timeInput: true,
        changeMonth: true,
        changeYear: true,
        dateFormat: 'yy-mm-dd',

        timeFormat: 'HH:mm', hourMin: 5, hourMax: 24, hourGrid: 3, minuteGrid: 15
});
//
$("#addEventEndDate").datetimepicker({
    timeInput: true,
    changeMonth: true,
    changeYear: true,
    dateFormat: 'yy-mm-dd',
    timeFormat: 'HH:mm', hourMin: 5, hourMax: 24, hourGrid: 3, minuteGrid: 15
}); 

//選擇時,穫取值
function selectDate(start, end, allDay) {
    //$('#addEventStartDate').datetimepicker();
    $('#addDialog').dialog('open');
    $("#addEventStartDate").val("" + $.fullCalendar.formatDate(start, "YYYY-MM-DD HH:mm")); //text //標簽span $.fullCalendar.formatDate(start, "yyyy/MM/dd HH:mm");
    $("#addEventEndDate").val("" + $.fullCalendar.formatDate(end, "YYYY-MM-DD HH:mm")); //text $.fullCalendar.formatDate(end, "yyyy/MM/dd HH:mm");
    //$("#addEventStartDate").datetimepicker('setDate', $.fullCalendar.formatDate(start, "YYYY-MM-DD HH:mm")); //設置值,日期格式還存在不相符問題
    addStartDate = start;
    addEndDate = end;
    globalAllDay = allDay;
    //alert(allDay);
}

function updateEventOnDropResize(event, allDay) {

    //alert("allday: " + allDay);
    var eventToUpdate = {
        id: event.id,
        start: event.start
    };

    if (event.end === null) {
        eventToUpdate.end = eventToUpdate.start;
    }
    else {
        eventToUpdate.end = event.end;
    }

    var endDate;
    if (!event.allDay) {
        endDate = new Date(eventToUpdate.end + 60 * 60000);
        endDate = endDate.toJSON();
    }
    else {
        endDate = eventToUpdate.end.toJSON();
    }

    eventToUpdate.start = eventToUpdate.start.toJSON();
    eventToUpdate.end = eventToUpdate.end.toJSON(); //endDate;
    eventToUpdate.allDay = event.allDay;

    PageMethods.UpdateEventTime(eventToUpdate, UpdateTimeSuccess);
}

function eventDropped(event, dayDelta, minuteDelta, allDay, revertFunc) {
    if ($(this).data("qtip")) $(this).qtip("destroy");

    updateEventOnDropResize(event);
}

function eventResized(event, dayDelta, minuteDelta, revertFunc) {
    if ($(this).data("qtip")) $(this).qtip("destroy");

    updateEventOnDropResize(event);
}
//隻可輸入數字,字母,中文,中文標點符號 20170417 塗聚文 EDIT
function checkForSpecialChars(stringToCheck) {
    var pattern = /[^A-Za-z0-9 |\u4e00-\u9fa5|\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/;  //A-Za-z0-9 
    return pattern.test(stringToCheck);
}
//是否整天時間
function isAllDay(startDate, endDate) {
    var allDay;

    if (startDate.format("HH:mm:ss") == "00:00:00" && endDate.format("HH:mm:ss") == "00:00:00") {
        allDay = true;
        globalAllDay = true;
    }
    else {
        allDay = false;
        globalAllDay = false;
    }

    return allDay;
}
//提示內容
function qTipText(start, end, description) {
    var text;

    if (end !== null)
        text = "<strong>Start:</strong> " + start.format("YYYY-MM-DD hh:mm T") + "<br/><strong>End:</strong> " + end.format("YYYY-MM-DD hh:mm T") + "<br/><br/>" + description;
    else
        text = "<strong>Start:</strong> " + start.format("YYYY-MM-DD hh:mm T") + "<br/><strong>End:</strong><br/><br/>" + description;

    return text;
}

$(document).ready(function () { 

    // update Dialog 修改,刪除
    $('#updatedialog').dialog({
        autoOpen: false,
        width: 470,
        buttons: {
            "update": function () {
                //alert(currentUpdateEvent.title);
                var eventToUpdate = {
                    id: currentUpdateEvent.id,
                    title: $("#eventName").val(),
                    description: $("#eventDesc").val()
                };

                if (checkForSpecialChars(eventToUpdate.title) || checkForSpecialChars(eventToUpdate.description)) {
                    alert("please enter characters: 可輸入數字,字母,中文,中文標點符號, 空格");
                }
                else {
                    PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
                    $(this).dialog("close");

                    currentUpdateEvent.title = $("#eventName").val();
                    currentUpdateEvent.description = $("#eventDesc").val();
                    $('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
                }

            },
            "delete": function () {

                if (confirm("do you really want to delete this event?")) {

                    PageMethods.deleteEvent($("#eventId").val(), deleteSuccess);
                    $(this).dialog("close");
                    $('#calendar').fullCalendar('removeEvents', $("#eventId").val());
                }
            }
        }
    });

    //add dialog 添加
    $('#addDialog').dialog({
        autoOpen: false,
        width: 470,
        buttons: {
            "Add": function () {
                //alert("sent:" + addStartDate.format("dd-MM-yyyy hh:mm:ss tt") + "==" + addStartDate.toLocaleString());
                var eventToAdd = {
                    title: $("#addEventName").val(),
                    description: $("#addEventDesc").val(),
                    start: addStartDate.toJSON(), //addStartDate.toJSON()
                    end:addEndDate.toJSON(),
                    allDay: isAllDay(addStartDate, addEndDate)
                };

                if (checkForSpecialChars(eventToAdd.title) || checkForSpecialChars(eventToAdd.description)) {
                    alert("please enter characters: 可輸入數字,字母,中文,中文標點符號, 空格");
                }
                else {
                    //alert("sending " + eventToAdd.title);

                    PageMethods.addEvent(eventToAdd, addSuccess);
                    $(this).dialog("close");
                }
            }
        }
    });

    var date = new Date();
    var d = date.getDate();
    var m = date.getMonth();
    var y = date.getFullYear();
    var options = {
        weekday: "long", year: "numeric", month: "short",
        day: "numeric", hour: "2-digit", minute: "2-digit"
    };

    $('#calendar').fullCalendar({
        theme: true,
        header: {
            left: 'prev,next today customBtn',
            center: 'title',
            right: 'month,agendaWeek,agendaDay,listWeek' //顯示日程列表
        },
        customButtons: {
            customBtn: {
                text: 'Custom Button',
                click: function () {
                    alert('This custom button is hot!
 类似资料: