製品検索サイト完成

会社で業務の合間にコツコツ作っていた製品検索サイトがようやく完成しました。写真も1/4くらいは私が撮影したのを使っていて、生成AIの助けは借りましたが、基本的に一人で作って仕上げました。60歳過ぎて初めてLaravel/PHPでちゃんとしたサイトを作るということに成功して、ちょっと達成感があります。

製品検索ページの実装ほぼ終了

会社のWebサイト用の製品検索ページの実装がほぼ終わりました。後はデータの登録だけ。(ってこれが結構大変ですが)
今回、完全な分業で、データベースの登録、検索画面の作成等は私がLaravel/phpを使ってやりました。データベース関係はphpMyAdminもフルに使っています。そしてその後の細かな機能(選択状態クリア、検索結果画面に品名コピーボタン追加、検索件数表示、検索待ちの時にカーソルをグルグルに変える、選択候補の絞り込み、等々)は全てChatGPT4oにJavaScriptで書かせ、そっちは私は1行も書いていません。ともかくLaravelのphpのソースを渡して、「この機能追加して」で済むので、タイピングの手間、JavaScriptの書き方の調査だけでも大変な省力化です。おそらくベタに私が全部書いたら10倍の時間がかかったと思います。
ただChatGPT4oもちょっと抜けている所があって、新しい機能を追加すると前の機能が動かなくなるというのが多発しました。なのでソースは毎回渡した方が結果はいいようでした。

JavaScript: 動的な選択候補の絞り込み(2)

取り敢えず、スイッチの操作部種別を選んだら、それに対応する極数の候補を動的に絞り込むというJavaScriptのコードをChatGPT4oに作らせ動きました。最初は絞り込みの対応関係をJSONで書いてそれを読み込ませようとしたのですが、上手く動かないので結局元のHTML(blade)ファイルの中に書込む形になりました。あまり綺麗ではありませんが。しかしなかなか大変。書店でJavaScriptの本を何冊か立ち読みしてみましたが、現在選択されている候補を取得するとか、逆に候補を設定するとかはありましたが、動的な絞り込みまで載っている本は見つけられませんでした。
=========================================
<script>
document.addEventListener(‘DOMContentLoaded’, function() {
const switchOpPartSelect = document.querySelector(‘select[name=”switch_op_part_id”]’);
const switchPoleSelect = document.querySelector(‘select[name=”switch_pole_id”]’);

const allPoleOptions = [
@foreach ($switch_poles as $switch_pole)
{ id: “{{ $switch_pole->id }}”, text: “{{ $switch_pole->poles_number }}” },
@endforeach
];

switchOpPartSelect.addEventListener(‘change’, function() {
const selectedOpPartId = parseInt(this.value);
let filteredPoleOptions = [{ id: “1”, text: “-” }];

if ([2, 3, 5, 6].includes(selectedOpPartId)) {
filteredPoleOptions = filteredPoleOptions.concat(allPoleOptions.filter(option => [11, 12, 13, 14].includes(parseInt(option.id))));
} else if (selectedOpPartId === 4) {
filteredPoleOptions = filteredPoleOptions.concat(allPoleOptions.filter(option => [11, 12].includes(parseInt(option.id))));
} else if (selectedOpPartId === 7) {
filteredPoleOptions = [{ id: “1”, text: “-” }].concat(allPoleOptions);
} else {
filteredPoleOptions = [{ id: “1”, text: “-” }].concat(allPoleOptions);
}

switchPoleSelect.innerHTML = ”;
filteredPoleOptions.forEach(option => {
const newOption = document.createElement(‘option’);
newOption.value = option.id;
newOption.textContent = option.text;
switchPoleSelect.appendChild(newOption);
});
});

document.querySelector(‘form’).addEventListener(‘submit’, function() {
showLoadingMessage();
});

window.resetForm = function() {
document.querySelectorAll(‘select’).forEach(select => {
select.selectedIndex = 0;
});
document.querySelector(‘input[name=”type_name”]’).value = ”;

switchPoleSelect.innerHTML = ”;
[{ id: “1”, text: “-” }].concat(allPoleOptions).forEach(option => {
const newOption = document.createElement(‘option’);
newOption.value = option.id;
newOption.textContent = option.text;
switchPoleSelect.appendChild(newOption);
});
}
});

function showLoadingMessage() {
document.getElementById(‘loading-message’).style.display = ‘block’;
document.body.classList.add(‘loading’);
}
</script>

JavaScriptのフレームワーク

まがりなりにも、Laravel/PHPを使ったWebアプリの開発が最低レベルながら出来るようになり、次はインタラクティブ性向上のためJavaScriptのコードを書くという段階で、一応こんな本をポチってみました。今作っているレベルのものにはフレームワークは不要と思いますが、何かの時に役立つかもしれないと思って。
まあ生成AIが全部コード書いてくれる時代に、この手の自学自習は時代遅れなのかもしれませんが、最低限ボケ防止ぐらいにはなると思います。

Webページでのデータベース検索での、各オプションの候補の動的な絞り込み

Webサイトでのデータベース検索で、各オプションの選択肢で、あるオプションのある選択肢を選んだ時に、その選択肢の時だけに存在する他の選択肢を絞り込む(存在しないものを消す)という処理について、以前ChatGPT4に聞いたのですが、回答はDBの各テーブルにリレーション(belong toなど)を設定して、それを使ってJavaScriptで候補を絞り込むだったのですが、良く考えるとそれだと必ずDBへのアクセスが生じ、レスポンスが落ちます。なので、要は候補同士の相関をJSONで書いておいて、それをHTMLを開く時に最初に読むやり方の方がいいと思って、再度ChatGPT4に聞いたら、その考え方は正しいようです。
================

以前、あるオプションの選択肢の選択によって他のオプションの選択肢を絞り込む(限定する)処理についてお聞きしましたが、その時はきちんとDBで各オプションのリレーションを設定して、JavaScriptで処理するということでした。そのやり方だとサーバーへの問い合わせが必ず発生しレスポンスが落ちるのではないでしょうか。簡易的なやり方として、絞り込みの関係になるオプション同士の連携をJSONなどで書いておいて、それをHTMLを読み込む最初に読み込んでおいて絞り込みに使う、というやり方はどうでしょうか?
ChatGPT
はい、オプションの選択肢を事前にJSON形式で定義しておき、クライアント側で絞り込みを行う方法は、有効なアプローチの一つです。これにより、サーバーへのリクエストを減らし、レスポンスの速度を向上させることができます。以下に、その具体的な方法を示します。
1. JSONファイルの作成
まず、オプション同士の関係を定義したJSONファイルを作成します。このファイルをサーバーの静的な場所に置き、HTMLページがロードされたときに読み込むようにします。
例:options.json

json
コードをコピーする
{
“product_op_parts”: {
“1”: {
“series_names”: [1, 2, 3],
“poles”: [1, 2]
},
“2”: {
“series_names”: [2, 3],
“poles”: [2, 3]
}
},
“product_series_names”: {
“1”: {
“poles”: [1]
},
“2”: {
“poles”: [2, 3]
}
}
}
2. HTMLとJavaScriptの修正
次に、HTMLとJavaScriptを修正して、JSONファイルを読み込み、選択肢を絞り込む処理を追加します。
例:create.blade.php
html
コードをコピーする

 

<style>
/* … 既存のスタイル … */<br />
</style>
<main></main>&nbsp;
<div align=”center”><big><big><big><big>ABC株式会社</big></big></big></big></div>
<div align=”center”><big><big>ABC Co., Ltd.</big></big></div>
<form action=”{{ route(‘product_name.search’) }}” method=”POST”>@csrf
<div>
<h3>製品名検索 <small><small>Switch Product Search</small></small></h3>
各オプションをプルダウンリストから選択して、ページ下部の[検索]ボタンをクリックしてください。
Please select each option from the pull-down lists and press the search button at the bottom of the page.
<label><b>操作部種別</b> Type of Operational Parts</label>
<select name=”product_op_part_id”>
<option value=””>選択してください</option>@foreach ($product_op_parts as $product_op_part)
<option value=”{{ $product_op_part->id }}”>{{ $product_op_part-&gt;sosabu_type }}</option>@endforeach
</select>
</div>
<div><label><b>シリーズ名</b> Series Name</label>
<select name=”product_series_name_id”>
<option value=””>選択してください</option>@foreach ($product_series_names as $product_series_name)
<option value=”{{ $product_series_name->id }}”>{{ $product_series_name-&gt;series_name }}</option>@endforeach
</select></div>
<div><label><b>極数</b> Number of Poles</label>
<select name=”product_pole_id”>
<option value=””>選択してください</option>@foreach ($product_poles as $product_pole)
<option value=”{{ $product_pole->id }}”>{{ $product_pole-&gt;poles_number }}</option>@endforeach
</select></div>
<!– 他のフォーム要素 –>
<table border=”0″ width=”350″ frame=”void” rules=”none”>
<tbody>
<tr>
<td><input type=”submit” value=”検索/ Search”></td>
<td>@csrf
<button type=”submit”>選択肢のクリア/ To clear options</button></td>
</tr>
</tbody>
</table>
<script>
document.addEventListener(‘DOMContentLoaded’, function() {
let options = {};
fetch(‘/path/to/options.json’)
.then(response => response.json())
.then(data => {
options = data;
});
const opPartSelect = document.getElementById(‘product_op_part_id’);
const seriesNameSelect = document.getElementById(‘product_series_name_id’);
const poleSelect = document.getElementById(‘product_pole_id’);
opPartSelect.addEventListener(‘change’, function() {
const selectedOpPart = this.value;
updateOptions(selectedOpPart, ‘series_names’, seriesNameSelect);
updateOptions(selectedOpPart, ‘poles’, poleSelect);
});
seriesNameSelect.addEventListener(‘change’, function() {
const selectedSeriesName = this.value;
updateOptions(selectedSeriesName, ‘poles’, poleSelect);
});
function updateOptions(selectedId, relationKey, targetSelect) {
const relatedOptions = options.product_op_parts[selectedId] ? options.product_op_parts[selectedId][relationKey] : [];
Array.from(targetSelect.options).forEach(option => {
option.style.display = relatedOptions.includes(parseInt(option.value)) ? ‘block’ : ‘none’;
});
targetSelect.value = ”;
}
});
</script>

まとめ
オプションの関係性をJSONファイルで定義します。
HTMLページロード時にこのJSONファイルを読み込みます。
JavaScriptで選択されたオプションに基づいて、他のオプションの選択肢を絞り込みます。
この方法で、クライアントサイドでの処理が行われるため、サーバーへのリクエストが減少し、レスポンスの速度が向上します。

今晩もChatGPT4との対話によるラテン語の日本語訳

今晩もChatGPT4とラテン語の日本語訳についての対話。直訳調を自然な日本語にするのに役立っています。
(マックス・ヴェーバーの「ローマ土地制度史」)

You
またマックス・ヴェーバーの「ローマ土地制度史」からです。これはHyginが述べているローマの植民市が近隣の元からあるゲマインデの土地を奪って自分達のformaに書き入れた、という箇所への注釈です。ラテン語の日本語訳をチェック願います。
=======
… multis … erepta sunt territoria et divisi sunt complurium municipiorum agri et una limitatione comprehensa sunt: facta est pertica omnis, id est omnium territoriorum, coloniae ejus in qua coloni deducti sunt. Ergo fit ut plura territoria unam faciem limitationis accipiant.
領土が多くの者によって奪われ、多くのゲマインデの土地が分割され、一本の境界線によって接収された:全ての土地に測量棒が設置され、それは領土全域に渡っての土地であり、その土地はそこにおいて植民者に分け与えられた。それ故に(近隣ゲマインデは)結果的には複数箇所の領土について、そういった境界変更を受け入れざるを得なかった。
ChatGPT
あなたの日本語訳は、原文の意味を大まかに正確に捉えていますが、少し修正を加えてより明確に表現することができます。特に、「una limitatione comprehensa sunt」の部分は「一本の境界線によって接収された」よりも、「一つの測量によって包括された」と訳す方が、原文の「limitatio」が土地測量のプロセスを指す用語であることを踏まえると適切です。「facta est pertica omnis」の「pertica」は測量の際に使われる測量棒を指しますが、ここではメタファーとして全領土を指しています。
修正案:
「多くの地域から領土が奪われ、数多くのゲマインデ(市町村)の土地が分割され、一つの測量によって包括された:すなわち、全ての領土が測量棒によって測られ、その土地はそこに定住する植民者たちに割り当てられた植民市のものとなった。その結果、複数の領土が一つの測量の形式を受け入れることになった。」
この修正では、測量プロセスと土地割り当ての概念をより正確に反映し、「一つの測量によって包括された」という表現で、複数の領土が単一の測量プロセスによって一つの植民市の領域に組み込まれたことを明確にしています。また、「全ての領土が測量棒によって測られ」という表現は、この土地測量が領土全域に及んだことを示しています。最後に、結果として近隣のゲマインデが新たに定められた境界を受け入れることを強いられたことを、「複数の領土が一つの測量の形式を受け入れることになった」と表現しています。
User
元のドイツ語にformaの中に書き入れるとあるので、以下のように修正しました。
「多くの地域から領土が奪われ、多くのゲマインデ(市町村)の土地が分割され、一つの測量図の中に包括された:すなわち、全ての領土が測量され、そ(れら)の土地はそこに定住する植民者たちに割り当てられて植民市のものとなった。その結果、複数の領土が一つの測量図に包括されることを(各ゲマインデは)受け入れさせられることになった。」
ChatGPT
この修正は、ドイツ語の原文に言及する「formaの中に書き入れる」という点を考慮に入れた適切な修正です。この修正案では、「forma」を「測量図」と訳し、その中に複数の領土が包括されることを明確にしています。この表現は、土地がどのようにして植民市に割り当てられ、そのプロセスがどのように記録されたかを示しており、原文の意図をより正確に反映しています。
また、「受け入れさせられることになった」という表現は、他のゲマインデがこの新しい状況を受け入れることを余儀なくされたというニュアンスを効果的に伝えています。これにより、ローマの植民地拡張が周辺のゲマインデに及ぼした影響と、そのプロセスがどのように公式の記録に反映されたかについての理解が深まります。
全体的に、この修正案は原文の内容を正確に伝え、読み手が文脈をより深く理解するのを助けるものになっています。非常に良い修正です。
User
いつも有り難うございます。助かりました。
ChatGPT
いつでもお役に立てて嬉しいです。また何かご質問があれば、遠慮なくお知らせくださいね。お手伝いできることがあれば幸いです。

Laravelの勉強し直し(3)

日本語の書籍でのLaravelの勉強しなおしは、会社のサーバーでやっていて危うくサーバーをアクセス不能にしかけた(間違えて全てのファイルのオーナーをapacheにしてしまった)ので、結局自分の家のサーバーで再度やり直し。結局一通りの学習は終わりました。しかし作ろうとしているのは、Webサイト上での製品検索なので、登録とか修正とかをWebサイト上で行うことはないので、あまり参考にはなっていません。登録とか修正はmigrationとか使わずphpMyAdminでやれば十分です。

IT本の再増殖

IT関係の本は引っ越しの時にかなり整理しましたが、また増えつつあります。JavaScript本は会社で作成中のWeb商品検索データベースでの検索時に、あるオプションを選択した時に、別のオプションの選択肢を絞り込むという機能のためです。(PHPだとページ更新しないと絞り込みが反映されません。)Laravelのオライリー本は、これの古い版を持っているんですが、Laravelのバージョンアップが激しすぎて内容がかなり変わっているんで仕方なくまた最新版を買いました。日本語のLaravel本は、ほとんどが取り敢えずサンプルのデータベースWebアプリを作りましょう、で終わっていて、入門用以外の内容が乏しいです。まあWordPressとPHP/LaravelとJavaScriptをマスターすれば、大抵のHPは構築出来ると思います。

Laravelの勉強し直し(2)


Laravelの勉強しなおしも、かなり進みました。
実際にはWebページから検索とその結果表示が出来れば良いので、Web画面からの登録とか編集機能は不要ですが、一応学習しています。
それより欲しいのはオプションを選択して絞り込み検索なのですが、その際に機能1の選択がこれだったら機能2のこのオプションは無し、みたいな制御をどうしようか考えています。前の会社の時に外注に出してやってもらったのはJSONでルールを記述していました。Laravelでも似たような感じになるのではないかとおもいます。
https://zenn.dev/arsaga/articles/ad20f42ed399ed

ヴェーバーの翻訳にChatGPT4は本当に役立ちます。

ヴェーバーのドイツ語の翻訳に、ChatGPT4は本当に役立ちます。というか木村相良の辞書のVerfassungの項の記述に「組織・体制」の意味が書いていないのがおかしいのですが。下記の回答見ても分るように、ChatGPT4はこの「ローマ土地制度史」の全体の内容をきちんと理解しています。現在日本にヴェーバーの研究者は掃いて捨てるほどいますが、「ローマ土地制度史」をこのレベルで読んでいる人は一人もいないと思います。(かつてはいたと思いますが。)

====================================================
User
以下のドイツ語はマックス・ヴェーバーの「ローマ土地制度史」の一部です。この文章でのFlurverfassungはどういう意味でしょうか?つまり耕地に対する法律の意味なのか、それとも耕地に関する記述でしょうか?
Mag die colonia, die »Bauernschaft« — nach Mommsens Ansicht — die verjüngte Projektion der gentilen Flurverfassung sein, so ist sie ausserdem doch auch eine Organisation zur Abwehr dritter in einem befestigten Ort, also einer Stadt.

ChatGPT
この文脈での「Flurverfassung」は、特定の耕地に関する制度や組織の枠組みを指す用語として使われています。ドイツ語で「Flur」は「耕地」「畑地」などの意味があり、「Verfassung」は「憲法」「制度」「組織の枠組み」などの意味を持ちます。したがって、「Flurverfassung」は直訳すると「耕地の制度」または「耕地の組織の枠組み」となり、耕地に対する法的または組織的な枠組み、つまり耕地に関する制度や管理の仕組みを意味しています。
この文章の中でマックス・ヴェーバーは、ローマの土地制度、特に「colonia」や「Bauernschaft(農民社会)」が、古代の「gentilen Flurverfassung(氏族的な耕地制度)」の影響を受けて形成されたものであると述べています。しかし、それに加えて、「colonia」は外部からの防衛を目的とした固定された場所、すなわち都市としての機能も持っていたと指摘しています。
従って、この文脈では「Flurverfassung」は、耕地に関する記述やその管理・運用に関する法的または組織的な枠組みを指していると解釈できます。この用語は、単に法律の意味ではなく、より広い意味で耕地に関する社会的・組織的な制度を含む概念として使用されているようです。