最小限の設定
.env
APP_NAME=Laravel
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
とDB接続情報
config/app.php
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'fallback_locale' => 'en',
'faker_locale' => 'ja_JP',
Practical Resources for Legacy Code Programmer
APP_NAME=Laravel
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
とDB接続情報
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'fallback_locale' => 'en',
'faker_locale' => 'ja_JP',
1..env ファイル
DB設定を書き換え
APP_ENV=local をproduction に
APP_DEBUG=true をfalseに
2.ドキュメントルート以下のindex.php(設置ディレクトリ)
laravel(本体)のパスを書き換え
autoload.php
app.php
3.ファイルのパーミッション設定
/laravel/storage/logs/laravel.log
/laravel/bootstrap/cache directory
/laravel/storage/framework/sessions
/laravel/storage/framework/views
bootstrapを使っていて
<button type="button">
<span data-feather="trash-2"></span>削除
</button>
buttonにこんな感じでfeatherのアイコンを入れています。
で、この画面のこの部分をajaxで読み込んでロードしなおしたりすると、アイコンが消えてしまいます。
そんな時は、
$.get(url, function(data) {
$('#result').html(data);
feather.replace(); // Featherアイコンを再適用
});
というようにすればよい。
reactかはてまたvue.jsか、と苦闘を続けているが、どうもよくない。reactにしてもvue.jsにしても最初はよかったのかもしれないが、バージョンが上がるにつれて、どうも自分の世界に全てをひきこもうとしているのが見え見えで、なんか使いづらいのだ。
ということで他を探すということにしてみた。
Alpine.jsね。
https://alpinejs.dev/
早速サンプルソース行ってみよう。
まず、親画面ですね。
index.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>モーダルウィンドウの例</title>
<link rel="stylesheet" href="styles.css">
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body x-data="app()">
<div x-data="{ open: false }">
<button @click="showModal = true">モーダルを開く1</button>
<p>選択結果:<span x-text="result"></span></p>
<div x-show="showModal" class="modal" @click.away="open = false">
<?php include ("fetch_content.php"); ?>
</div>
<div x-show="showModalSub" class="modal">
<?php include ("fetch_content_sub.php"); ?>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
ボタンをクリックでモーダルを開く、ということで、ボタンとそのモーダル一つ目と二つ目を用意している。モーダルの中身はphpから読み込む設定で、ここではincludeを使っているが、別にここは普通にテンプレートでよい。
で、モーダルの中身であるfetch_content.phpは、
<div class="modal-content">
<span @click="showModal = false" class="close">×</span>
<div>
<div>
<form>
<label for="name">名前:</label>
<input type="text" id="name" name="name" x-model="name">
<button type="button" @click="search()">検索</button>
</form>
</div>
<div x-html="searchResults"></div>
</div>
</div>
こんな感じ。モーダルを閉じる×印と、検索フォーム、結果表示部分で構成されている。
検索ボタンをクリックでsearch()関数に渡しているが、ここはphpのresult.phpを実行して結果をsearchResultsに書き込む想定だ。
result.php
<table>
<tbody>
<tr>
<th>ID</th>
<th>社名</th>
<th>日付</th>
</tr>
<tr @click="selectRow(1)">
<td>1</td>
<td>アイワ</td>
<td>2024-05-30</td>
</tr>
<tr @click="selectRow(2)">
<td>2</td>
<td>ソニー</td>
<td>2024-05-31</td>
</tr>
<tr @click="selectRow(3)">
<td>3</td>
<td>松下電器</td>
<td>2024-05-31</td>
</tr>
</tbody>
</table>
で、さらにこの結果表の行クリックselectRow()で次のモーダルを開き、また、そこで検索し、その結果行をクリックで、選択したIDを親画面に表示させようと、そういう構成である。
二つ目のモーダル
fetch_content_sub.php
<div x-show="showModalSub" class="modal">
<div class="modal-content">
<span @click="showModalSub = false" class="close">×</span>
<div>
<div>
<form>
<input type="hidden" id="company_id" name="company_id" x-model="companyId">
<label for="name">TEL:</label>
<input type="text" id="tel" name="tel" x-model="tel">
<button type="button" @click="searchSub()">検索</button>
</form>
</div>
<div x-html="searchSubResults"></div>
</div>
</div>
</div>
2つめモーダルで検索結果。
result_sub.php
<table>
<tbody>
<tr>
<th>ID</th>
<th>名前</th>
<th>日付</th>
</tr>
<tr @click="selectSubRow(1)">
<td>1</td>
<td>山田一郎</td>
<td>2024-05-30</td>
</tr>
<tr @click="selectSubRow(2)">
<td>2</td>
<td>田中花子</td>
<td>2024-05-31</td>
</tr>
</tbody>
</table>
ということで準備できたので、javascriptを書いていこう。
script.js
function app() {
return {
showModal: false,
showModalSub: false,
result: "",
companyId: "",
name: "",
tel: "",
searchResults: "",
searchSubResults: "",
async search() {
try {
const response = await fetch(`result.php?name=${this.name}`);
this.searchResults = await response.text();
} catch (error) {
console.error("Error fetching the content:", error);
}
},
selectRow(id) {
this.companyId = id;
this.showModalSub = true;
},
async searchSub() {
try {
const response = await fetch(
`result_sub.php?tel=${this.tel}&company_id=${this.companyId}`
);
this.searchSubResults = await response.text();
} catch (error) {
console.error("Error fetching the content:", error);
}
},
selectSubRow(id) {
this.showModalSub = false;
this.showModal = false;
this.result = id;
this.searchResults = "";
this.searchSubResults = "";
this.name = "";
this.tel = "";
},
};
}
おっつ。これはなかなかシンプルじゃない?
ちなみにcssはこんな感じで。
styles.css
/* モーダルのスタイル */
.modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
最小限の構成での動作検証だが、開いたモーダルで検索し、表示された結果表から行選択で選択した値を親画面に反映する、という機能を考えてみた。
というかほぼchatgptに書いてもらったのがこの内容である。
まずは親画面
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>モーダルウィンドウの例</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<button id="openModalBtn">モーダルを開く</button>
<p>選択結果:<span id="result"></span></p>
<div id="modal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<div id="modal-body">
<!-- PHPから取得したコンテンツがここに表示されます -->
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
モーダルを開くボタンをモーダルから受け取った変数の表示、それとモーダルの入れ物(閉じるボタンを含む)だけ、というシンプルなものである。
次にモーダルの中身だ。こちらはphpから読み込む想定である。
<div>
<form id="searchForm">
<label for="name">名前:</label>
<input type="text" id="name" name="name">
<button type="button" onclick="search()">検索</button>
</form>
</div>
<div id="searchResults">
<!-- 検索結果の表がここに表示されます -->
</div>
こんな感じ。検索ボタンクリックでjsの関数に渡して、結果を下のdiv内に表示しようというもの。
で、問題のjsだが、
document.addEventListener("DOMContentLoaded", function () {
var modal = document.getElementById("modal");
var openModalBtn = document.getElementById("openModalBtn");
var closeModalSpan = document.getElementsByClassName("close")[0];
var modalBody = document.getElementById("modal-body");
openModalBtn.onclick = function () {
fetch("fetch_content.php")
.then((response) => response.text())
.then((data) => {
modalBody.innerHTML = data;
modal.style.display = "block";
})
.catch((error) => {
console.error("Error fetching the content:", error);
});
};
closeModalSpan.onclick = function () {
modal.style.display = "none";
};
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
});
function search() {
// 検索フォームから名前を取得
var name = document.getElementById("name").value;
// ここでサーバーに名前を送信して検索結果を取得する処理を行います
// 以下はダミーの検索結果を表示するコードです
var searchResults = [
{ id: 1, name: "山田太郎", date: "2024-05-30" },
{ id: 2, name: "田中花子", date: "2024-05-31" },
];
// 検索結果を表示する
displayResults(searchResults);
}
function displayResults(results) {
var table = "<table><tr><th>ID</th><th>名前</th><th>日付</th></tr>";
// 検索結果をテーブル形式に整形
for (var i = 0; i < results.length; i++) {
table +=
"<tr onclick='selectRow(" +
results[i].id +
")'><td>" +
results[i].id +
"</td><td>" +
results[i].name +
"</td><td>" +
results[i].date +
"</td></tr>";
}
table += "</table>";
// 検索結果を表示
document.getElementById("searchResults").innerHTML = table;
}
function selectRow(id) {
// ダブルクリックされた行のIDを親画面に表示
modal.style.display = "none";
document.getElementById("result").innerHTML = id;
}
ついでにcssは
/* モーダルのスタイル */
.modal {
display: none; /* デフォルトは非表示 */
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
これで問題なく動作する。いいよね。
いろいろ問題はあると思うが。