テーブルのソート

ソート・並び替えは、一旦、表示を全て消して、配列の中身を並び替えて再表示しています。ソートの関数はarr.sort(function(a, b){});を使います。
並び替え関数

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

リフェレンス:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>テーブルのソート機能</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<link rel="stylesheet" href="css/styles.css">
	<style>
	</style>
</head>
<body>
	<table>
	<thead>
		<tr>
			<th data-type="string">Name</th>
			<th data-type="string">Team</th>
			<th data-type="number">Score</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>murakami</td>
			<td>orange</td>
			<td class="score">35</td>
		</tr>
		<tr>
			<td>Kuriyama</td>
			<td>orange</td>
			<td class="score">5</td>
		</tr>
		<tr>
			<td>murata</td>
			<td>Yellow</td>
			<td class="score">77</td>
		</tr>
		<tr>
			<td>sakurai</td>
			<td>green</td>
			<td class="score">68</td>
		</tr>
		<tr>
			<td>midokura</td>
			<td>yellow</td>
			<td class="score">48</td>
		</tr>
		<tr>
			<td>kimoto</td>
			<td>green</td>
			<td class="score">97</td>
		</tr>
	</tbody>
	</table>
	<div>
	</div>
	<script src="js/main.js">
	</script>
</body>
</html>

js.main.js

(function(){
	'use strict';

	 var ths = document.getElementsByTagName('th');
	 var sortOrder = 1;

	 function rebuildTobody(rows){
	 		var tbody = document.querySelector('tbody');

	 		while(tbody.firstChild){
	 			tbody.removeChild(tbody.firstChild);
	 		}
	 		var i;
	 		for(i = 0; i < rows.length; i++){
	 			tbody.appendChild(rows[i]);
	 		}
	 	}

	 	function updateClassName(th){
			var k;
	 		for(k = 0; k < ths.length; k++){
	 		ths[k].className = '';
	 		}
	 		th.className = sortOrder === 1 ? 'asc' : 'desc';
	 	}

	 	function compare(a, b, col, type){
	 			var _a = a.children[col].textContent;
	 			var _b = b.children[col].textContent;
	 			if (type === "number"){
	 			_a = _a * 1;
	 			_b = _b * 1;
	 			}
	 			else if (type === "string") {
	 			_a = _a.toLowerCase();
	 			_b = _b.toLowerCase();
	 			}
	 			if (_a < _b){
	 				return -1;
	 			}
	 			if (_a > _b) {
	 				return 1;
	 			}
	 			return 0;
	 	}

	 	function sortRows(th){
	 		var rows = Array.prototype.slice.call(document.querySelectorAll('tbody > tr'));
	 		var col = th.cellIndex;
	 		var type = th.dataset.type;

	 		rows.sort(function(a, b){
	 			return compare(a, b, col, type) * sortOrder;
	 		});
	 		return rows;
	 	}

	 	function setup(){
	 		var i;
	 		for (i = 0; i < ths.length; i++){
	 		ths[i].addEventListener('click', function(){
	 		var rows;
	 		rows = sortRows(this);
	 		rebuildTobody(rows);	 		
	 		updateClassName(this);
	 		sortOrder *= -1;
	 	});
	  }
	}
	 	setup();
})();

css/styles.css

body {
	font-size: 16px;
	font-family: Verdana, sans-serif;
}
table {
	width: 540px;
	margin: 20px auto;
	border-collapse: collapse;
}
th, td {
	width: 180px;
	box-sizing: border-box;
	border: 1px solid #e9eae8;
	padding: 8px 20px;
}
tbody tr:nth-child(odd){
	background: #f8f8f8;
}
.score {
	text-align:right;
}
th {
	cursor: pointer;
}

th:after {
	content: '\f0dc';
	font-family: FontAwesome;
	font-size: 12px;
	color: #ccc;
	float: right;
	padding-top: 4px;
	font-weight: normal;
}

th.asc:after {
	content: '\f0de';
	font-family: FontAwesome;
	color: #000;
}
th.desc:after {
	content: '\f0dd';
	font-family: FontAwesome;
	color: #000;
}

単語帳

表と裏をdocument.getElementByIdで、divタグのidから呼び出しています。CSS3でカードflipはtransform: rotateY(180deg);と表現します。

リフェレンス
KeyCode:The KeyboardEvent.keyCode read-only property represents a system and implementation dependent numerical code identifying the unmodified value of the pressed key.

keyup:Bind an event handler to the “keyup” JavaScript event, or trigger that event on an element.

コード

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>単語帳</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<style>
	body {
		margin: 0;
		background: #e0e0e0;
		text-align: center;
		font-family: Verdana, sans-serif;
		color: #fff;
	}
	#btn {
		width: 200px;
		margin: 0 auto;
		padding: 7px;
		border-radius: 5px;
		background: #00aaff;
		box-shadow: 0 4px 0 #0088cc;
		cursor: pointer;
	}
	#btn:hover{
		opacity: 0.8;
	}
	#card {
		margin: 60px auto 20px;
		width: 400px;
		height: 100px;
		cursor: pointer;
		font-size: 38px;
		line-height: 100px;
		perspective: 100px;
		transform-style: preserve-3d;
		transition: transform .8s;
	}
	#card-front, #card-back {
		display: block;
		width: 100%;
		height: 100%;
		border-radius: 5px;
		position: absolute;
		backface-visibility: hidden;
	}
	#card-front {
		background: #fff;
		color: #333;
	}
	#card-back {
		background: #00aaff;
		transform: rotateY(180deg);
	}
	.open {
		transform: rotateY(180deg);
	}
	</style>
</head>
<body>
	<div id="card">
		<div id="card-front"></div>
		<div id="card-back"></div>
	</div>
	<div id="btn">NEXT</div>
	<script>
	(function(){
		'use strict'

		var words = [
			{'en': 'read', 'ja':'読む'},
			{'en': 'write', 'ja':'書く'},
			{'en': 'eat', 'ja':'食べる'},
			{'en': 'run', 'ja':'走る'},
			{'en': 'walk', 'ja':'歩く'}
		];

		var card = document.getElementById('card');
		var cardFront = document.getElementById('card-front');
		var cardBack = document.getElementById('card-back');
		var btn = document.getElementById('btn');

		card.addEventListener('click', function(){
			flip();
		});
		btn.addEventListener('click', function(){
			next();
		});

		function next(){
			if (card.className === 'open') {
				card.addEventListener('transitioned', setCard);
				flip();
			} else {
				setCard();
			}

		}

		function setCard(){
			var num = Math.floor(Math.random() * words.length);
			cardFront.innerHTML = words[num]['en'];
			cardBack.innerHTML = words[num]['ja'];
			card.removeEventListener('transitioned', setCard);
		}

		setCard();

		window.addEventListener('keyup', function(e){
			if (e.keyCode === 70){
				flip();
			} else if (e.keyCode === 78){
				next();
			}
		});

		function flip(){
			card.className = card.className === '' ? 'open' : '';
		}
	
	})();
	</script>
</body>
</html>

スロットマシーン

classNameにactive、inactiveをつけて、opacityを変えます。また、addEventListenerで、クリックされた際に、Math.floor(Math.random() * (n + 1))で、ランダムな数値を取得し、配列に返し、それぞれの数字が一致するか、チェックして、opacityを変えます。実際のスロットは、もう少し複雑な設定方法だと思いますが、原理としては近いものがあるのではないでしょうか。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Slot Machine</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<style>
		body {
			background: #e0e0e0;
			font-family: Arial, sans-serif;
			text-align: center;
			font-size: 16px;
			margin-top: 30px;
		}
		.panel {
			display: inline-block;
			width: 60px;
			padding: 7px;
			border-radius: 5px;
			margin-bottom: 15px;
			color: #00aaff;
			font-weight: bold;
			font-size: 32px;
			line-height: 64px;
			background: #fff;
		}
		.panel + .panel {
			margin-left: 10px;
		}
		.panel.unmatched {
			opacity: 0.5;
		}
		.btn {
			display: inline-block;
			width: 60px;
			padding: 7px;
			border-radius: 5px;
			margin-bottom: 15px;
			color: #fff;
			box-shadow: 0 4px 0 #0088cc;
			background: #00aaff;
			cursor: pointer;
		}
		.btn + .btn {
			margin-left: 10px;
		}
		.btn.inactive{
			opacity: 0.5;
		}
		#spinButton {
			margin: 0 auto;
			width: 240px;
			padding: 7px;
			border-radius: 5px;
			color: #fff;
			box-shadow: 0 4px 0 #e91b0c;
			background: #f44336;
			cursor: pointer;
		}
		#spin.inactive{
			opacity: 0.5;
		}
	</style>
</head>
<body>
	<div>
	  <div class="panel" id="panel0">?</div>
	  <div class="panel" id="panel1">?</div>
	  <div class="panel" id="panel2">?</div>
	</div>
	<div>
		<div class="btn inactive" id="btn0">STOP</div>
		<div class="btn inactive" id="btn1">STOP</div>
		<div class="btn inactive" id="btn2">STOP</div>
	</div>
	<div id="spinButton">SPIN</div>
	<script>
		(function(){
			'use strict';

			var panels = ['1', '3', '5', '7'];
			var timers = [];
			var results = [];
			var stopCount = 0;
			var isPlaying = false;

			var panel0 = document.getElementById('panel0');
			var panel1 = document.getElementById('panel1');
			var panel2 = document.getElementById('panel2');
			var btn0 = document.getElementById('btn0');
			var btn1 = document.getElementById('btn1');
			var btn2 = document.getElementById('btn2');
			var spinButton = document.getElementById('spinButton');

			spinButton.addEventListener('click', function(){
				if (isPlaying) return;
				isPlaying = true;
				this.className = 'inactive';
				btn0.className = 'btn';
				btn1.className = 'btn';
				btn2.className = 'btn';
				panel0.className = 'panel';
				panel1.className = 'panel';
				panel2.className = 'panel';

				runSlot(0, panel0);
				runSlot(1, panel1);
				runSlot(2, panel2);
			});

			function runSlot(n, panel){
				panel.innerHTML = panels[Math.floor(Math.random() * panels.length)];
				timers[n] = setTimeout(function(){
					runSlot(n, panel)
				}, 50);
			}

			btn0.addEventListener('click', function(){
				stopSlot(0, panel0, this);
			});
			btn1.addEventListener('click', function(){
				stopSlot(1, panel1, this);
			});
			btn2.addEventListener('click', function(){
				stopSlot(2, panel2, this);
			});

			function stopSlot(n, panel, btn){
				if (!isPlaying || results[n] !== undefined) return;
				btn.className = 'btn inactive';
				clearTimeout(timers[n]);
				results[n] = panel.innerHTML;
				stopCount++;

				if (stopCount === 3){
					checkResults();

					isPlaying = false;
					timers = [];
					results = [];
					stopCount = 0;
					spintButton.ClassName = '';
				}
			}

			function checkResults(){
				if (results[0] !== results[1] && results[0] !== results[2]) {
						panel0.className = 'panel unmatched';
			}
				if (results[1] !== results[0] && results[1] !== results[2]) {
						panel1.className = 'panel unmatched';
			}
				if (results[2] !== results[0] && results[2] !== results[1]) {
						panel2.className = 'panel unmatched';
			}
		}
		})();
	</script>
</body>
</html>

font-awesomeのハンバーガー

document.getElementByIdで、アイコンがクリックされた際に、document.body.className = ‘menu-open’とdocument.body.className = ”を返します。なお、font-awesomeはCDNで取得します。

https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style>
		body {
			padding: 0;
			margin: 0;
			font-family: Verdana, sans-serif;
			background: #eee;
			color: #333;
			padding: 8px;
			box-sizing: border-box;
			width: 100%;
			height: 100%;
			overflow-x: hidden;
		}
		#cover {
			background: #000;
			opacity: 0.6;
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left:0;
			z-index:1;
			display: none;

		}
		#menu {
			z-index:2;
			position: absolute;
			top: 0;
			right: -180px;
			color: #fff;
			background: #4c81e9;
			padding: 8px;
			box-sizing: border-box;
			width: 180px;
			min-height: 100%;
			transition: .4s;
		}

		#show, #hide {
			float: right;
			cursor: pointer;
		}
		body.menu-open {
			overflow-y: hidden;

		}
		body.menu-open #cover {
			display: block;

		}
		body.menu-open #menu {
			right: 0;
			
		}
	</style>
</head>
<body>

	<i class="fa fa-bars" id="show"></i>
		<h1>Hello</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
	<div id="cover"></div>

	<div id="menu">
		<i class="fa fa-times" id="hide"></i>
		<ul>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
		</ul>
	</div>
	<script>
	(function(){
		'use strict';

		var show = document.getElementById('show');
		var hide = document.getElementById('hide');

		show.addEventListener('click', function(){
			document.body.className = 'menu-open'
		});

		hide.addEventListener('click', function(){
			document.body.className = ''
		});
	})();
	</script>
</body>
</html>

ハンバーガーメニュー

addEventListener:The EventTarget.addEventListener() method registers the specified listener on the EventTarget it’s called on. The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest).

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style>
		body {
			padding: 0;
			margin: 0;
			font-family: Verdana, sans-serif;
		}
		#menu {
			position: absolute;
			top: 0;
			right: 0;
			color: #fff;
			background: #4c81e9;
			box-sizing: border-box;
			width: 180px;
			min-height: 100%;
		}
		#main {
			z-index: 1;
			background: #eee;
			position: absolute;
			top: 0;
			left: 0;
			color: #333;
			padding: 8px;
			box-sizing: border-box;
			width: 100%;
			height: 100%;
			overflow: auto;
			transition: .4s;
		}
		#main.menu-open {
			left: -180px;
		}
		#show {
			float: right;
			cursor: pointer;
		}
	</style>
</head>
<body>
	<div id="menu">
		<ul>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
		</ul>
	</div>
	<div id="main">
		<i class="fa fa-bars" id="show"></i>
		<h1>Hello</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
	</div>
	<script>
	(function(){
		'use strict';

		var show = document.getElementById('show');
		var main = document.getElementById('main');

		show.addEventListener('click', function(){
			if (main.className === 'menu-open'){
				main.className = '';
			} else {
				main.className = 'menu-open';
			}
		});
	})();
	</script>
</body>
</html>

クリッカブルタブメニュー

%e7%84%a1%e9%a1%8c

event.preventDefault()
If this method is called, the default action of the event will not be triggered.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<style>
		body {
			padding:0;
			margin:0;
			font-family: Verdana, sans-serif;
		}
		.container {
			padding: 0;
			margin: 30px auto;
			width: 500px;
			background: #dce0e0;
		}
		ul.menu {
			list-style: none;
			padding: 0;
			margin: 0;
			font-size: 0;
		}
		ul.menu li {
			display: inline-block;
		}
		ul.menu li a {
			display: inline-block;
			font-size: 14px;
			width: 80px;
			height: 20px;
			line-height: 20px;
			text-align: center;
			text-decoration: none;
			padding: 7px;
			color: #333;
		}
		ul.menu li a.active {
			background: #353d3e;
			color: #fff;
		}
		ul.menu li a:not(.active):hover {
			opacity: 0.5;
			transition: .8s;
		}
		.content {
			font-size: 14px;
			padding: 7px 10px;
			line-height: 1.4;
			background: #353d3e;
			color: #fff;
			min-height: 150px;
			display: none;
		}
		.content.active {
			display: block;
		}
	</style>
</head>
<body>
<div class="container">
	<ul class="menu">
		<li><a href="#" data-id="about" class="active  menu_item">About</a></li>
		<li><a href="#" data-id="service" class="menu_item">Service</a></li>
		<li><a href="#" data-id="contact" class="menu_item">Contact</a></li>
	</ul>
	<div class="content active" id="about">
	Lorem1 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
	<div class="content" id="service">
	Lorem2 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
	<div class="content" id="contact">
	Lorem3 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
<p></p>
<script>
	(function(){
		'use strict'

		var menuItems = document.getElementsByClassName('menu_item');
		var contents = document.getElementsByClassName('content');

		var i;

		for (i=0; i < menuItems.length; i++){
			menuItems&#91;i&#93;.addEventListener('click', function(e){
				e.preventDefault();

				var i;
				for (i=0; i < menuItems.length; i++){
					menuItems&#91;i&#93;.className = 'menu_item';
				}
				this.className = 'menu_item active';

				var i;
				for (i=0; i < contents.length; i++){
					contents&#91;i&#93;.className = 'content';
				}
				document.getElementById(this.dataset.id).className = 'content active';

			});
		}

	})();
</script>
</body>
</html>

functions, config

%e7%84%a1%e9%a1%8c

<?php

function connectDb(){
  try {
    return new PDO(DSN, DB_USER, DB_PASSWORD);
  } catch (PDOException $e){
    echo $e->getMessage();
    exit;
  }
}

function h($s){
  return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
}

function setToken(){
  if (!isset($_SESSION['token'])){
    $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
  }
}

function checkToken(){
  if (empty($_POST['token']) || $_POST['token'] != $_SESSION['token']){
    echo "不正な処理です!";
    exit;
  }
}
/*

create database contact_php;
grant all on contact_php.* to dbuser@localhost identified by 'xxxx';

use contact_php

create table entries (
  id int not null auto_increment primary key,
  name varchar(255),
  email varchar(255),
  memo text,
  created datetime,
  modified datetime
);

alter table entries add status enum('active', 'deleted') default 'active' after memo;
*/

define('DSN','mysql:host=localhost;dbname=contact_php');
define('DB_USER','dbuser');
define('DB_PASSWORD','xxxx');

define('SITE_URL','http://192.168.33.10:8000');
define('ADMIN_URL', SITE_URL.'/admin/');

error_reporting(E_ALL & ~E_NOTICE);
session_set_cookie_params(0, '');

edit, delete

<?php

require_once('../config.php');
require_once('../functions.php');

session_start();
$dbh = connectDb();

if (preg_match('/^&#91;1-9&#93;&#91;0-9&#93;*$/', $_GET&#91;'id'&#93;)){
    $id = (int)$_GET&#91;'id'&#93;;
} else{
    echo "不正なIDです!";
    exit;
}

if ($_SERVER&#91;'REQUEST_METHOD'&#93; != "POST"){
  setToken();

  $stmt = $dbh->prepare("select * from entries where id = :id limit 1");
  $stmt->execute(array(":id" => $id));
  $entry = $stmt->fetch() or die("no one found!");
  $name = $entry['name'];
  $email = $entry['email'];
  $memo = $entry['memo'];

} else {
  checkToken();

  $name = $_POST['name'];
  $email = $_POST['email'];
  $memo = $_POST['memo'];

  $error = array();

  if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $error['email'] = 'メールアドレスの形式が正しくありません';
  }
  if($email == ''){
    $error['email'] = 'メールアドレスを入力してください';
  }
  if($memo == ''){
    $error['memo'] = '内容を入力してください';
  }
  if(empty($error)){

    $sql = "update entries set
            name = :name,
            email = :email,
            memo = :memo,
            modified = now()
            where id = :id";
     $stmt = $dbh->prepare($sql);
     $params = array(
       ":name" => $name,
       ":email" => $email,
       ":memo" => $memo,
       ":id" => $id
     );
     $stmt->execute($params);

    header('Location: '.ADMIN_URL);
    exit;
  }
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>データの編集</title>
</head>
<body>
  <h1>データの編集</h1>
  <form method="POST" action="">
    <p>お名前:<input type="text" name="name" value="<?php echo h($name); ?>"></p>
    <p>メールアドレス*:<input type="text" name="email" value="<?php echo h($email); ?>">
    <?php if($error&#91;'email'&#93;){ echo h($error&#91;'email'&#93;); } ?></p>
    <p>内容*:</p>
    <p><textarea name="memo" cols="40" rows="5"><?php echo h($memo); ?></textarea>
    <?php if($error&#91;'memo'&#93;){ echo h($error&#91;'memo'&#93;); } ?></p>
    <p><input type="submit" value="更新"></p>
    <input type="hidden" name="token" value="<?php echo h($_SESSION&#91;'token'&#93;); ?>">
  </form>
  <p><a href="<?php echo ADMIN_URL; ?>">戻る</a>
</body>
</html>

delete

<?php

require_once('../config.php');
require_once('../functions.php');

$dbh = connectDb();

$id = (int)$_POST&#91;'id'&#93;;

$dbh->query("update entries set status = 'deleted' where id = $id");

echo $id;

thanks

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>ありがとうございました!</title>
</head>
<body>
  <h1>ありがとうございました!</h1>
  <p></p>
  <p><a href="index.php">お問い合わせフォームに戻る</a></p>
</body>
</html>

問い合わせ管理システム

index.php

<?php

require_once('config.php');
require_once('functions.php');

session_start();
if ($_SERVER&#91;'REQUEST_METHOD'&#93; != "POST"){
  setToken();
} else {
  checkToken();

  $name = $_POST&#91;'name'&#93;;
  $email = $_POST&#91;'email'&#93;;
  $memo = $_POST&#91;'memo'&#93;;

  $error = array();

  if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $error&#91;'email'&#93; = 'メールアドレスの形式が正しくありません';
  }
  if($email == ''){
    $error&#91;'email'&#93; = 'メールアドレスを入力してください';
  }
  if($memo == ''){
    $error&#91;'memo'&#93; = '内容を入力してください';
  }
  if(empty($error)){
    $dbh = connectDb();

    $sql = "insert into entries
            (name, email, memo, created, modified)
            values
            (:name, :email, :memo, now(), now())";
    $stmt = $dbh->prepare($sql);
    $params = array(
      ":name" => $name,
      ":email" => $email,
      ":memo" => $memo
    );
    $stmt->execute($params);

    header('Location: '.SITE_URL.'/thanks.html');
    exit;
  }
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
  <h1>お問い合わせフォーム</h1>
  <form method="POST" action="">
    <p>お名前:<input type="text" name="name" value="<?php echo h($name); ?>"></p>
    <p>メールアドレス*:<input type="text" name="email" value="<?php echo h($email); ?>">
    <?php if($error&#91;'email'&#93;){ echo h($error&#91;'email'&#93;); } ?></p>
    <p>内容*:</p>
    <p><textarea name="memo" cols="40" rows="5"><?php echo h($memo); ?></textarea>
    <?php if($error&#91;'memo'&#93;){ echo h($error&#91;'memo'&#93;); } ?></p>
    <p><input type="submit" value="送信"></p>
    <input type="hidden" name="token" value="<?php echo h($_SESSION&#91;'token'&#93;); ?>">
  </form>
  <p><a href="<?php echo ADMIN_URL; ?>">管理者ページ</a>
</body>
</html>

contact

<?php

require_once('../config.php');
require_once('../functions.php');

$dbh = connectDb();

$entries = array();

$sql = "select * from entries where status = 'active' order by created desc";

foreach($dbh->query($sql) as $row){
  array_push($entries, $row);
}

// var_dump($entries);
// exits;

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>お問い合わせ一覧</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
  <h1>一覧データ</h1>
  <p><span id="num"><?php echo count($entries); ?></span>件あります。</p>
  <ul>
    <?php foreach($entries as $entry): ?>
      <li id="entry_<?php echo h($entry&#91;'id'&#93;); ?>"><?php echo h($entry&#91;'email'&#93;); ?>
        <a href="edit.php?id=<?php echo h($entry&#91;'id'&#93;); ?>">[編集]</a>
        <span class="deleteLink" data-id="<?php echo h($entry&#91;'id'&#93;); ?>">[削除]</span>
      </li>
    <?php endforeach; ?>
  </ul>
  <style>
  .deleteLink{
    color: blue;
    cursor: pointer;
  }
  </style>
  <p><a href="<?php echo SITE_URL; ?>">お問い合わせフォームに戻る</a></p>
  <script>
  $(function(){
    $('.deleteLink').click(function(){
      if (confirm("削除してもよろしいですか?")){
        var num = $('#num').text();
        num--;
        $.post('./delete.php', {
           id: $(this).data('id')
          }, function(rs){
            $('#entry_' + rs).fadeOut(800);
            $('#num').text(num);
          });
      }
      });
    });
  </script>
</body>
</html>