#試しにグーグルライクなスケジュールソフトを作ってみました。
週末、調べて作ってみました
ざっくり以下の環境が必要です。
1 fullcalendar V5
2 node.js 6.14.5
3 Express 4.17.1(6.14.5で動くもの)
4 sqlite3 5.0(6.14.5で動くもの)
#ざっくり表のHTMLソースです
以下のようになっています。
これがV5の情報がなくて英語のマニュアルを読んで
作っていました。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link href='../lib/main.css' rel='stylesheet' />
<script src='../lib/main.js'></script>
<script src='../lib/locales/ja.js'></script>
<script>
//alert(data);
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
now: '2020-06-07',
locale:'ja',
scrollTime: '00:00', // undo default 6am scrollTime
editable: true, // enable draggable events
selectable: true,
aspectRatio: 1.8,
headerToolbar: {
left: 'today prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineThreeDays,timeGridWeek,dayGridMonth,listWeek'
},
initialView: 'resourceTimelineDay',
views: {
resourceTimelineThreeDays: {
type: 'resourceTimeline',
duration: { days: 3 },
buttonText: '3 days'
}
},
resourceAreaHeaderContent: '営業先',
resources: [
{ id: 'a', title: '営業先A' },
{ id: 'b', title: '営業先 B', eventColor: 'green' },
{ id: 'c', title: '営業先 C', eventColor: 'orange' },
{ id: 'd', title: '営業先 D', children: [
{ id: 'd1', title: '子 営業先 D1' },
{ id: 'd2', title: '子 営業先 D2' }
] },
{ id: 'e', title: '営業先 E' },
{ id: 'f', title: '営業先 F', eventColor: 'red' },
{ id: 'g', title: '営業先 G' },
{ id: 'h', title: '営業先 H' ,eventColor: 'orange' },
{ id: 'i', title: '営業先 I' },
{ id: 'j', title: '営業先 J', eventColor: 'green' },
{ id: 'k', title: '営業先 K' },
{ id: 'l', title: '営業先 L' },
{ id: 'm', title: '営業先 M' },
{ id: 'n', title: '営業先 N' },
{ id: 'o', title: '営業先 O' },
{ id: 'p', title: '営業先 P' },
{ id: 'q', title: '営業先 Q' },
{ id: 'r', title: '営業先 R' },
{ id: 's', title: '営業先 S' },
{ id: 't', title: '営業先 T' },
{ id: 'u', title: '営業先 U' },
{ id: 'v', title: '営業先 V' },
{ id: 'w', title: '営業先 W' },
{ id: 'x', title: '営業先 X' },
{ id: 'y', title: '営業先 Y' },
{ id: 'z', title: '営業先 Z' }
],
eventResize: function (info) {
//alert(info.event.id + " was dropped on " + info.event.start.toISOString());
//if (!confirm("Are you sure about this change?")) {
// info.revert();
//} else {
//}
//////////////////////////////////
var event = calendar.getEventById(info.event.id);
var resources = event.getResources();
var resourceIds = resources.map(function (resource) { return resource.id });
////////////////////
var request = new XMLHttpRequest();
var req = 'http://157.7.138.66:3000/api/updata?resourceId=' + resourceIds + '&start=' + info.event.start.toISOString() + '&end=' + info.event.end.toISOString() + '&id=' + info.event.id
request.open('GET', req, true);
request.responseType = 'json';
request.onload = function () {
var data = this.response;
console.log(data);
//alert(data);
calendar.addEventSource(data);
calendar.refetchEvents();
calendar.render();
};
request.send();
},
eventDrop: function (info) {
//alert(info.event.id + " was dropped on " + info.event.start.toISOString());
//if (!confirm("Are you sure about this change?")) {
// info.revert();
//} else {
//}
//////////////////////////////////
var event = calendar.getEventById(info.event.id);
var resources = event.getResources();
var resourceIds = resources.map(function (resource) { return resource.id });
////////////////////
var request = new XMLHttpRequest();
var req = 'http://157.7.138.66:3000/api/updata?resourceId=' + resourceIds + '&start=' + info.event.start.toISOString() + '&end=' + info.event.end.toISOString() + '&id=' + info.event.id
request.open('GET', req, true);
request.responseType = 'json';
request.onload = function () {
var data = this.response;
console.log(data);
//alert(data);
calendar.addEventSource(data);
calendar.refetchEvents();
calendar.render();
};
request.send();
},
dateClick: function(info) {
//日付をクリックしたときの処理
//addEvent(calendar,info);
//あとで使う関数
alert(info);
},
select:function(event, jsEvent){
var title = prompt('予定を入力してください:', event.title);
if (title && title != "") {
alert("[" + title + "] 作成しました");
}
alert("開発未定");
//if(title && title!=""){
// event.title = title;
// calendar.fullCalendar('updateEvent', event); //イベント(予定)の修正
//}else{
// calendar.fullCalendar("removeEvents", event.id); //イベント(予定)の削除
//}
}
});
var request = new XMLHttpRequest();
request.open('GET', 'http://157.7.138.66:3000/api/photo/list', true);
request.responseType = 'json';
request.onload = function () {
var data = this.response;
console.log(data);
//alert(data);
calendar.addEventSource(data);
calendar.refetchEvents();
calendar.render();
};
request.send();
calendar.render();
});
</script>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 50px auto;
}
</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>
#DB側を少し解説
基本的にDBは更新と参照のみ。フレームワークはexpressを使っています。
//データーベースファイル SQLITE3
var dbpath = "data.db";
//AJAXから受け取る情報をJSONで返す(ロード時の参照)
app.get("/api/photo/list", function (req, res, next) {
db.all('SELECT id,resourceId,start,end,title from event', function (err, rows) {
if (err) {
throw err;
}
rows.forEach(function (row) {
//console.log(row);
data.push(row);
console.log(data);
});
res.json(data);
data = [];
});
});
//AJAXから受け取る情報をSQLアップデートで更新する
app.get("/api/updata", function (req, res, next) {
var sql = 'UPDATE event SET resourceId ="' + req.query.resourceId + '", start ="' + req.query.start + '" , end = "' + req.query.end +'" WHERE id = ' + req.query.id;
db.run(sql, data, function (err) {
if (err) {
return console.error(err.message);
}
});
});
#だいたいはソースにある通りです。
裏のロジックは後日 執筆します。それよりもソースが欲しい方は以下で連絡してもらえば
メールと一緒に解説します。※2020/08/20 裏のロジックを執筆しました。
#サンプルサイト
http://157.7.138.66:3000/index2
サンプルサイトです。
ソースプログラムが欲しい方は
以下のメールアドレスからどうぞ連絡をください。
qqmdはちsrきゅうk@docomonet.jp
平仮名は数値でお願いします(スパム除け)
*サンプルサイトは期間限定で公開しています。
*仮IDはusername
*仮PWはpasswordです