PHP
select
Ajax

Ajaxで連動したselectタグを生成する方法 (PHP)


やりたいこと


  • 親selectタグで選択された項目にカテゴライズされた子selectタグをAjaxで生成する

例)自動車メーカー(TOYOTA,NISSAN,HONDA)に連動した各メーカーの車種のselectタグを生成

*セキュリティ対策は実装出来ておりません。

スクリーンショット 2016-06-04 20.52.15.png

スクリーンショット 2016-06-04 20.52.30.png

スクリーンショット 2016-06-04 20.52.43.png


  • 自動車メーカー maker テーブル(親)

id
maker_name

1
TOYOTA

2
NISSAN

3
HONDA


  • 車種テーブル model テーブル(子)

id
maker_id
model_name

1
1
アクア

2
1
アルフォード

3
1
カローラ

4
1
プリウス

5
1
クラウン

6
2
ジューク

7
2
ノート

8
2
キューブ

9
2
セレナ

10
3
オデッセイ

11
3
フィット

12
3
N-BOX

13
3
ステップワゴン

14
3
CR-V

15
3
CR-Z


index.php

<?php

//DBへ接続
try {
$dsn = 'mysql:host=localhost;dbname=car_maker;charset=utf8';
$user = 'username'; //root
$pass = 'password'; //root
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false));
} catch (Exception $e) {
exit('データベース接続失敗'.$e->getMessage());
}
//makerテーブル から値を取得し、 id と name を $maker_list配列 に格納
$sql = "SELECT * FROM maker";
$stmt = $pdo->query($sql);
$maker_list = array();
while($row = $stmt -> fetch(PDO::FETCH_ASSOC)){
$maker_list[$row['id']] = $row['maker_name'];
}
?>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-1.12.4.min.js" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//selectタグ(親) が変更された場合
$('[name=car_maker]').on('change', function(){
var maker_val = $(this).val();

//maker_val値 を select.php へ渡す
$.ajax({
url: "select.php",
type: "POST",
dataType: 'json',
data: {
maker_id: maker_val
}
})
.done(function(data){
//selectタグ(子) の option値 を一旦削除
$('.car_model option').remove();
//select.php から戻って来た data の値をそれそれ optionタグ として生成し、
// .car_model に optionタグ を追加する
$.each(data, function(id, name){
$('.car_model').append($('<option>').text(name).attr('value', id));
});
})
.fail(function(){
console.log("失敗");
});

});
});
</script>
<title>Ajax Sample</title>
</head>
<body>
<h1>Ajax Sample</h1>
<div class="">
<span>自動車メーカー:</span>
<select class="car_maker" name="car_maker">
<option>選択して下さい</option>
<?php foreach($maker_list as $key => $maker_name){
echo '<option name="" value="'.$key.'">'.$maker_name.'</option>';
}?>
</select>
<span>車種:</span>
<select class="car_model" name="car_model">
<option class="">選択して下さい</option>
</select>
</div>
</body>
</html>



select.php

<?php

//直接のページ遷移を阻止
$request = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
if($request !== 'xmlhttprequest') exit;
//DBへの接続
//本来は db_connect関数 を作成して、DRYにした方が良いです。
try {
$dsn = 'mysql:host=localhost;dbname=car_model;charset=utf8';
$user = 'username';
$pass = 'password';
$pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false));
}
catch (Exception $e) {
exit('データベース接続失敗'.$e->getMessage());
}
//Ajaxで渡ってきた値をもとに modelテーブル から該当する model を抽出
$maker_no = $_POST['maker_no'];
$sql = 'SELECT * FROM model WHERE maker_id = :maker_id';
$stmt=$pdo->prepare($sql);
$stmt->bindValue(':maker_id', (int)$maker_no, PDO::PARAM_INT);
$stmt->execute();

//抽出された値を $model_list配列 に格納
$model_list = array();
while($row = $stmt -> fetch(PDO::FETCH_ASSOC)){
$model_list[$row['id']] = $row['maker_name'];
}
header('Content-Type: application/json');
//json形式で index.php へバックする
echo json_encode($model_list);
?>