【授業ノート】php × jQuary × Ajax ハイウェイバスの予約システム

授業でやったプログラムを、覚え書きも兼ねて置いておきます。
※マキノ先生の作ったコードです。

※必要なファイルは最下段にあります。

あぶらぼうず

授業でやったものなので操作は限定的です。

  • 日付は3-14分しか反応しない
  • プルダウンで選択し、予約したい席番号をクリックして緑色にする
  • 灰色の部分はすでに予約済み。白い席のみ予約可能
  • 下部の「決定」を押す
  • 再読み込みをして再び3-14を選択
  • 先ほど選んだ席が予約済みの灰色になる

実際の動き
(※この記事を読んだ人が片っ端から座席を予約してしまうと、全部灰色になって無反応になる可能性があります)(※予約はおひとり1シートでお願いします)

https://berrysystems.sakura.ne.jp/karasumaru/karasumaru2019/001highwaybus/seat.php

基本操作

データベース側:

  • xamppを立ち上げる
  • ApacheとMySQLのstartを押す
  • MySQLのadminを押してphpMyAdminを起動
  • phpMyAdminでデータベース「highwaybus」を新規作成。
    そこにsqlファイルをインポート
  • これはうろ覚えですが
    あらかじめ同じ名前のテーブルを作っておいたかもしれない
    (seatsテーブル)(インポートするときは同名のテーブルが必要だった気がする)
  • データベース側は以上

ファイル側:

  • htdocsフォルダ内に「highwaybus」フォルダを新規作成、
    そこに必要なファイルをダウンロードする
  • htdocsフォルダはこのあたりにある
  • こんな階層になります
  • この階層の1つ上に「jquery-3.4.1.min.js」があるようにしてください
    (htsocsのルート)
  • chromeでhttp://localhost/を開き、
    そこからhighwaybus → seat.phpを開く
  • ファイル側は以上

kue

ファイル

ダウンロードは自己責任でお願いします。
何があっても当方は責任を持ちませんのであしからずご了承ください。

そもそもgithubに不慣れで何か問題ありましたら申し訳ありません

https://github.com/karasumaru/jugyo_highwaybus

github 授業ハイウェイバス

githubを見るのが面倒な人用
つかれてきたので誤字雑字ご容赦

seat.php

<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>座席予約</title>
		<link rel="stylesheet" href="css/style.css">
		<script src="../jquery-3.4.1.min.js"></script>
	</head>
	<body>
		<header>
			<h1>本日、明日、明後日のバスの予約</h1>
			<img src="car_bus.png">
		</header>
		
		<div id="container">
			<p>10:00発 大阪行き(1日1便)</p>
			<p>
				<select id="ymd">
					<option value="">日付の選択</option>
					<option value="2020-03-14">2020-03-14</option>
					<option value="2020-03-15">2020-03-15</option>
					<option value="2020-03-16">2020-03-16</option>
				</select>
			</p>
			
			<div id="front">進行方向↑</div>
			<div id="bus">
			</div>
			<p id="end"><button id="b1">決定</button></p>
		</div>

		<script src="js/seat.js"></script>		
	</body>
</html>

config.php

<?php
//setting
//環境によって変える

//テスト環境用
$host = "localhost";
$dbname = "highwaybus";
$dbuser = "root";
$dbpass = "";

//本番環境用
/*
$host = "xxx";
$dbname = "highwaybus";
$dbuser = "xxx";
$dbpass = "xxx";
*/

$dsn = "mysql:host={$host};dbname={$dbname};charset=utf8";
$pdo = new PDO($dsn,$dbuser,$dbpass);

/*
//定数を使うやり方
define("HOST_NAME","localhost");
define("DB_NAME","highwaybus");
define("DB_USER","root");
define("DB_PASS","");
echo HOST_NAME;
*/

?>

api/get_seat.php

<?php
if(empty($_GET["ymd"])){
	exit();
}
require_once("../config.php");

$sql="SELECT * from seats WHERE ymd=:ymd";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":ymd",$_GET["ymd"],PDO::PARAM_STR);
$stmt->execute();

$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

$json = json_encode($data);//api
echo $json;
?>

api/set_seat.php

<?php
if(empty($_POST["s"]) || empty($_POST["ymd"])){
	exit();
}
require_once("../config.php");

$sql="UPDATE seats SET reserved = 1";
$sql .= " WHERE ymd=:ymd AND seat_id=:seat_id";
$stmt = $pdo->prepare($sql);

//配列化
$sArr = explode(",",$_POST["s"]);

foreach($sArr as $val){
	$stmt->bindValue(":ymd",$_POST["ymd"],PDO::PARAM_STR);
	$stmt->bindValue(":seat_id",$val,PDO::PARAM_INT);
	$stmt->execute();
}

?>

js/seat.js

$(function(){
	//console.log("hoge");
	var seats = [];//配列

	$('#ymd').on('change',function(){
		$.ajax({
			url:'api/get_seat.php',
			type:'get',
			data:{'ymd':$('#ymd').val()},
			dataType:'json',
		})
		.done(function(d){
			//console.log(d);
			$('#bus').empty();


			for(i=0; i<d.length; i++){
				seats[d[i].seat_id] = 0;//予約まだしていません
				console.log(seats);

				var elehoge = $('<div>').text(d[i].seat_id);
				//予約済みかしら
				if(d[i].reserved == 1){
					//予約済みクラスを付与
					elehoge.attr('class','reserved');
				}else{
					//まだ空ですよ
					elehoge.attr('class','emp');
				}
				$('#bus').append(elehoge);
			}

			/*空席のクリック*/
			$('#bus div.emp').on('click',function(){
				//console.log($(this).css('background-color'));
				var num = $(this).text();//クリックされた要素に何の座席番号が記述してあるか取得

				//背景色を変え座席番号を取得し配列に入れる
				if($(this).css('background-color')=='rgb(255, 255, 255)'){
					$(this).css('background','#afa');
					seats[num] = 1;
				}else{
					$(this).css('background','#fff');
					seats[num] = 0;
				}
			});


		})
		.fail(function(){
			alert('NG: cannot connect ajax');
		});
	});

	//決定ボタンを押したとき
	$('#b1').on('click',function(){
		console.log(seats);

		//配列はそのままで送れないので文字列づくり
		var seatStr = "";//初期値は空文字
		for(var i=1; i<seats.length ; i++){//座席番号は1から始まるが勝手に0番が付与されているので-1する
			if(seats[i]==1){//席が予約されていたら
				seatStr += i + ',';//席番号とカンマをつなげていく。予約席番だけが追加される
			}
		}

		//最後のカンマだけは取りたい
		var s = seatStr.substr(0,seatStr.length -1);
		//console.log(s);

		//ajax通信で送信
		$.ajax({
			url:'api/set_seat.php',
			type:'post',
			data:{'ymd':$('#ymd').val(), 's': s},
		})
		.done(function(){
			console.log('ok');
		})
		.fail(function(){
			alert('NG');
		});
	});

});

css/style.css

body{
	background-color: #eee;
	margin:0;
	padding:0;
}
h1{
	margin:0;
	padding:0;
}
header{
	margin: 0 auto;
	text-align:center;
	background-color: #ccc;
}
header img{
	width:100px;
}
#container{
	width: 80%;
	margin: auto;
}
#front{
	text-align:center;
	/*border: solid 1px #555;*/
	padding: 1rem;
	border-radius: 2rem 2rem 0 0;
	background-color: #fff;
}
#bus{
	background-color: #fff;
	display:flex;
	flex-wrap:wrap;
	box-sizing: border-box;
	padding: 1rem;
}
#bus div{
	width: 22.5%;
	line-height: 3;
	text-align:center;
	box-sizing: border-box;
	border: solid 1px #555;
	background: #fff;
	margin:1rem 0;
}
#bus div:nth-child(4n+2){
	margin-right: 10%;
}
#bus div.reserved{/*予約済みのところ*/
	background: #6f7478;
}
#bus div.emp{/*予約可能*/
	background: #fff;
	cursor:pointer;
}

#end{
	text-align: center;
}
select{
	font-size:1.02rem;
}

database

2+