はじめに
前回、前々回、前々々回を踏まえなんとか完成?まだまだ改良の余地はあるとは思いますが・・・
機能
- 履歴は5件
- 履歴が保存される
- テンプレも変更可能
- インポート、エクスポート可能(localStorageが削除されても大丈夫なように)
ソース
CreateMail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>メール作成</title>
<style>
* {
font-family: MS Gothic;
font-size: 10.5pt;
}
html {
overflow-y: scroll;
}
button {
padding: 0.5em 1em;
border-radius: 5px;
}
input {
width: 99%;
height: 2em;
border-radius: 3px;
border: none;
}
select {
width: 100%;
height: 2em;
border-radius: 3px;
}
textarea {
border-radius: 3px;
border: none;
}
td {
border: 1px gray solid;
text-align: center;
border-radius: 3px;
}
#option {
color: gray;
margin: 1em 0em;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
vertical-align: middle;
display: table-cell;
height: 1.5em;
}
#template {
color: gray;
margin: 1em 0em;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
#main {
width: 800px;
margin-right: auto;
margin-left: auto;
}
#templateicon,#optionicon {
border: solid gray 1px;
border-radius: 3px;
}
</style>
<script>
var LOCAL_STORAGE_KEY = "createmailinfo";
var MAX_HISTORY_LENGTH = 5;
var info = {
subject : "[__category__]__who__[__mmdd__]",
body : "各位\n\nお疲れ様です。\n\n本日(__mmdd__)__hhmm__頃、__who__より電話連絡があり、\n"
+ "__reason____category__とのことです。\n\n以上、よろしくお願いいたします。\n",
hist : {
toaddr : [],
who : [],
category : ["遅刻", "全休", "半休"],
reason : [],
}
}
var reader = null;
function init() {
document.getElementById("createbtn").addEventListener("click", createEmail, true);
document.getElementById("resetbtn").addEventListener("click", reload, true);
document.getElementById("registbtn").addEventListener("click", registTemplate, true);
document.getElementById("option").addEventListener("click", toggleOption, true);
document.getElementById("template").addEventListener("click", toggleOption, true);
document.getElementById("importbtn").addEventListener("click", importHistory, true);
document.getElementById("exportbtn").addEventListener("click", exportHistory, true);
document.getElementById("removebtn").addEventListener("click", removeStorage, true);
document.getElementById("importfile").addEventListener("change", importFile, true);
document.getElementById("mmdd").value = getFormatDate("yyyy-mm-dd");
document.getElementById("hhmm").value = getFormatDate("HH:MM");
document.getElementById("mmdd").addEventListener("change", changeSubBody, true);
document.getElementById("hhmm").addEventListener("change", changeSubBody, true);
document.getElementById("who").addEventListener("input", changeSubBody, true);
document.getElementById("category").addEventListener("input", changeSubBody, true);
document.getElementById("reason").addEventListener("input", changeSubBody, true);
getInfoData();
document.getElementById("templatesubject").value = info.subject;
document.getElementById("templatebody").value = info.body;
setInfo();
changeSubBody();
reader = new FileReader();
reader.onload = loadedFile;
}
function createEmail(event) {
var toaddr = document.getElementById("toaddr").value;
var subject = document.getElementById("subject").value;
var body = document.getElementById("body").value;
var message = "以下の内容で、" + toaddr + "宛のメールを作成しますがよろしいでしょうか?\n"
+ "題名:" + subject + "\n=====本文 ここから=====\n" + body + "\n=====本文 ここまで=====";
if (confirm(message)) {
location.href = "mailto:" + encodeURIComponent(toaddr) + "?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body);
var data = {
toaddr : document.getElementById("toaddr").value,
who : document.getElementById("who").value,
category : document.getElementById("category").value,
reason : document.getElementById("reason").value,
};
for (var key in data) {
if (data[key]) {
var array = [data[key]];
for (var i = 0; i < info.hist[key].length; i++) {
if (i > MAX_HISTORY_LENGTH) {
break;
}
if (data[key] !== info.hist[key][i]) {
array.push(info.hist[key][i]);
}
}
info.hist[key] = array;
}
}
setInfo();
setInfoData();
}
}
function registTemplate(event) {
var subject = document.getElementById("templatesubject").value;
var body = document.getElementById("templatebody").value;
var message = "以下の内容で、テンプレートに登録しますがよろしいでしょうか?\n"
+ "※※※ 登録後、更新を行います。 ※※※\n"
+ "題名:" + subject
+ "\n=====本文 ここから=====\n" + body + "\n=====本文 ここまで=====\n";
if (confirm(message)) {
info.body = body;
info.subject = subject;
setInfoData();
reload();
}
}
function changeSubBody(event) {
var data = {
mmdd : ("" + document.getElementById("mmdd").value).split("-").join("/").substring(5),
hhmm : document.getElementById("hhmm").value,
who : document.getElementById("who").value,
category : document.getElementById("category").value,
reason : document.getElementById("reason").value,
};
var subject = info.subject;
var body = info.body;
for (var key in data) {
subject = subject.split("__" + key + "__").join(data[key]);
body = body.split("__" + key + "__").join(data[key]);
}
document.getElementById("subject").value = subject;
document.getElementById("body").value = body;
}
function setInfo() {
for (var key in info.hist) {
var element = document.getElementById(key + "list");
while (element.firstChild) { element.removeChild(element.firstChild); }
var val = info.hist[key];
if (val.length > 0) {
for (var i = 0; i < val.length; i++) {
var option = document.createElement("option");
option.setAttribute("value", val[i]);
element.appendChild(option);
}
}
}
}
function setInfoData() {
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(info));
}
function getInfoData(target) {
var data = target;
if (!data) {
data = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY));
}
if (data) {
for (var key in info.hist) {
try {
var item = data.hist[key];
if (item) {
var array = [];
info.hist[key] = array.concat(item);
}
} catch(e) {
console.log(e.message);
}
}
if (data.subject) {
info.subject = "" + data.subject;
}
if (data.body) {
info.body = "" + data.body;
}
}
}
function toggleOption(event) {
try {
var id = event.currentTarget.id;
var disp = document.getElementById(id + "content").style.display;
if (disp === "none") {
document.getElementById(id + "icon").innerHTML = "-";
document.getElementById(id + "content").style.display = "block";
} else {
document.getElementById(id + "icon").innerHTML = "+";
document.getElementById(id + "content").style.display = "none";
}
event.stopPropagation();
} catch(e) {
console.log(e.message);
}
}
function removeStorage(event) {
if (confirm("履歴を全て消しますがよろしいですか?")) {
localStorage.removeItem(LOCAL_STORAGE_KEY);
reload();
}
}
function importHistory(event) {
document.getElementById("importfile").click();
}
function importFile(event) {
var file = event.target.files[0];
reader.readAsText(file);
}
function loadedFile(event) {
var data = JSON.parse(event.target.result);
getInfoData(data);
setInfoData();
reload();
}
function exportHistory(event) {
var blob = new Blob([ JSON.stringify(info, null, "\t") ], {"type": "application/json"});
var url = URL.createObjectURL(blob);
var a = document.getElementById("exportlink");
a.setAttribute("download", LOCAL_STORAGE_KEY + "_" + getFormatDate("yyyymmddHHMMss") + ".json");
a.href = url;
a.click();
URL.revokeObjectURL(url);
a.href = null;
}
function getFormatDate(target) {
var format = null;
if (target) {
var now = new Date();
var yyyy = now.getFullYear();
var mm = (now.getMonth() < 9) ? ("0" + (now.getMonth() + 1)) : ("" + (now.getMonth() + 1));
var dd = (now.getDate() < 10) ? ("0" + now.getDate()) : ("" + now.getDate());
var HH = (now.getHours() < 10) ? ("0" + now.getHours()) : ("" + now.getHours());
var MM = (now.getMinutes() < 10) ? ("0" + now.getMinutes()) : ("" + now.getMinutes());
var ss = (now.getSeconds() < 10) ? ("0" + now.getSeconds()) : ("" + now.getSeconds());
format = target;
format = format.split("yyyy").join(yyyy);
format = format.split("mm").join(mm);
format = format.split("dd").join(dd);
format = format.split("HH").join(HH);
format = format.split("MM").join(MM);
format = format.split("ss").join(ss);
}
return format;
}
function reload() {
location.reload();
}
window.onload = init;
</script>
</head>
<body>
<div id="main">
<table>
<tr><td style="width: 80px">宛先</td><td style="width: 400px">
<input id="toaddr" type="text" list="toaddrlist" value="" placeholder="----- 送信先メールアドレスを設定してください。例)test@sample.com -----" />
<datalist id="toaddrlist"></datalist>
</td></tr>
<tr><td>月日</td><td><input id="mmdd" type="date" value="" /></td></tr>
<tr><td>時分</td><td><input id="hhmm" type="time" value="" /></td></tr>
<tr><td>誰?</td><td>
<input id="who" type="text" list="wholist" placeholder="----- 対象者を設定してください。例)鈴木さん -----" />
<datalist id="wholist"></datalist>
</td></tr>
<tr><td>区分</td><td>
<input id="category" type="text" list="categorylist" placeholder="----- 休暇区分を設定してください。例)遅刻 -----" />
<datalist id="categorylist"></datalist>
</td></tr>
<tr><td>理由</td><td>
<input id="reason" type="text" placeholder="----- 理由を設定してください。例)電車遅延の為、30分ほど -----" list="reasonlist" />
<datalist id="reasonlist"></datalist>
</td></tr>
<tr><td>題名</td><td><input id="subject" type="text" value="" placeholder="----- メールの題名を記入してください。 -----" /></td></tr>
<tr><td>本文</td><td><textarea id="body" cols="80" rows="12" placeholder="----- メールの本文を記入してください。 -----"></textarea></td></tr>
<tr><td style="border: none; text-align: right;" colspan="2">
<button id="resetbtn">リセット</button>
<button id="createbtn">メール作成</button>
</td></tr>
</table>
<div id="template">
<span id="templateicon">+</span>テンプレート
</div>
<div id="templatecontent" style="display: none;">
<table>
<tr><td style="width: 80px">宛先</td><td style="width: 400px">
<input id="templatesubject" type="text" value="" placeholder="----- メールの題名(テンプレート)を記入してください。 -----" />
</td></tr>
<tr><td>本文</td><td><textarea id="templatebody" cols="80" rows="12" placeholder="----- メールの本文(テンプレート)を記入してください。 -----"></textarea></td></tr>
<tr><td style="border: none; text-align: right;" colspan="2">
<button id="registbtn">登録</button>
</td></tr>
</table>
</div>
<div id="option">
<span id="optionicon">+</span>オプション
</div>
<div id="optioncontent" style="display: none;">
<button id="importbtn">インポート</button><span id="importarea" style="display: none;"><input id="importfile" type="file"></span>
<button id="exportbtn">エクスポート</button><a id="exportlink" download=""></a>
<button id="removebtn">ストレージ削除</button>
</div>
</div>
</body>
</html>
さいごに
ローカルHTMLでも案外アプリって作れるんですなぁ