アプリ版:「スタンプのみでお礼する」機能のリリースについて

質問させて下さい。
今PHP/MySQLを使って登録画面を作っています。
その中に【県】を選ぶと【その県の市】がセレクトメニューに表示され選択できるという2連セレクトメニューを入れています。
DBからセレクト項目を取得してくるため1回submitさせています。
そうすると、まだ入力を行っていない部分が【入力してください】と【確認】を1回押した状態になってしまうのです。

submitさせているので当然なのですが、回避する手段とかありませんか?

PHPは出来上がったものを購入しているので、いまいち命令の変え方が解りません。

宜しくお願いします。

A 回答 (10件)

やはりajaxを使うのがスマートだと思います。


以下にサンプル程度ですが、記載いたしますのでご参考にしていただければと思います。

■html
----------------------------------------------------
<script type="text/javascript">
<!--
function createXMLhttpObject(){
var XMLhttpObject = null;
try {
XMLhttpObject = new XMLHttpRequest();
} catch(e) {
try {
XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
XMLhttpObject = null;
}
}
}
return XMLhttpObject;
}

function prefChange(){
var val = document.getElementById("prefectures").value;
var sel = document.getElementById("city");
var xmlhttp = createXMLhttpObject();
if( xmlhttp) {
xmlhttp.open( "post", "json.php", true);
xmlhttp.onreadystatechange = function() {
if( xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var json = xmlhttp.responseText;
var opt = "";
var obj = eval("(" + json + ")");
for( ii=0; ii<obj.result.length; ii++){
opt += '<option value="'+ obj.result[ii].option + '">'+ obj.result[ii].value + '</option>\n';
}
sel.innerHTML = opt;
}
}
var sendData = "pref="+val;
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(sendData);
}

}
</script>

<form method="post" action="action.php">
<select id="prefectures" name="prefectures" onChange="prefChange();">
<option value="1">東京都</option>
<option value="2">埼玉県</option>
</select>

<select id="city" name="city"></select>

----------------------------------------------------

■json.php
----------------------------------------------------
<?php
$sql = SELECT option, value FROM T_CITY WHERE 都道府県=$_REQUEST['pref'];

//(省略:データを抽出するスクリプト)

//最終的なJSONの形は以下のようにする
header("Content-type: text/html; charset=utf-8\n\n");
print '{"result":[{"option":"1","value":"千代田区"},{"option":"2","value":"新宿区" },{"option":"3","value":"渋谷区" }]}';

?>
----------------------------------------------------

クロスブラウザや、文字コードなど検証していません。
Firefoxでちょっと試してみました。

よろしくお願いします。

この回答への補足

ご回答ありがとうございます。
さっそくやってみようと思います!

ちょっとPHPの使い方が特殊なので、すぐにうまくいくのかは解らないのですが、挑戦してみようと思います。

regist.phpで制御されているのですが、中身はhtmlがその制御に従ってクミ合わさっているものなので、json.phpをどう使用したらいいのかにつまずいてしまいました。

いろいろいじくってみようと思います。

補足日時:2009/09/29 18:10
    • good
    • 0

失礼しました。


この方法だとselectedしたものが表示されないですね。

ちょっとアクロバティクなやり方でスマートではないですが、
こんな感じだといかがでしょうか?

■html
----------------------------------------------------

var val = document.getElementById("prefectures").value;
var selected = document.getElementById("selected").value;

この1行を追加

for( ii=0; ii<obj.result.length; ii++){
if( obj.result[ii].option == selected) {
opt += '<option value="'+ obj.result[ii].option + '" selected>'+ obj.result[ii].value + '</option>\n';
} else {
opt += '<option value="'+ obj.result[ii].option + '">'+ obj.result[ii].value + '</option>\n';
}

このように変更


<form method="post" action="action.php">
<input type="hidden" name="selected" id="selected" value="$city.value">

この1行を追加

----------------------------------------------------

また不明点はお尋ねください。
    • good
    • 0
この回答へのお礼

数日頑張ってなんとか形になって来ました。
ぴったり同じ方法では組み方が複雑なので出来ませんでしたが、機能としては使えるようになりました。
記載して頂いたものをヒントにキレイにまとめられるようにちょっとづつ勉強して行きたいと思います。
ありがとうございました。
また、解らないことがあったら宜しくお願いします!

お礼日時:2009/10/05 16:04

こんにちは。



こんな感じだといかがでしょうか?
----------------------------------------------------



window.onload = function(){
if( document.getElementById("prefectures").value;){
prefChange();
}
}
//-->
</script>
----------------------------------------------------

この回答への補足

ありがとうございます。
今から試してみたいとおもいます!

補足日時:2009/10/01 18:03
    • good
    • 0

#7です。



1点補足させてください。
</script>の前に
//-->
を入れ忘れましたので、お願いします。

以下、アドバイスです。
いろいろ試す際は、もっともシンプルな形から試してみるのが
理解も深まっていいと思います。

目的は「都道府県を選択したら市区町村が非同期で変更される」
なので、まずここだけの簡単なソースで取り組むのがいいでしょう。
不明点はお気軽にお尋ねください。

頑張ってくださいね。

この回答への補足

やっぱり根本的なところから勉強しないとDBとのやり取りとAjax・PHPでHTMLを組み合わせるというのは難しいことなのですね。

katze_dogさんがおっしゃるとおりまずは、
DBから読み込んで来ることを捨てて、JSにDBと同じ形の物を作成し読み込ませる方法で、
「都道府県を選択したら市区町村が非同期で変更される」
というものを作ってみましたが、

登録画面なので、確認を押してみると、市町村の部分だけ記述が初期状態に戻ってしまいます。
戻らないいい方法ありますか?
DBから読み込むことをやめると今まで使っていた記憶しておく方法?が使えなくなってしまいました。

教えて頂けるとうれしいです。

補足日時:2009/10/01 17:10
    • good
    • 0

No.5です。


あまりにも手短に説明したので、雰囲気しか伝えられなかったかも知れず、すみませんでした。
ひとつの .php ファイルでいろいろと処理するのは、面倒がかかるので、制約さえなければ、他のご回答にあるように ajax を使うのがよいのでしょうね。
私は、ajax はまったくわからないので、php でごてごてに作ってしまってます。
今回は、無理やりでも先の回答の流れでいくつもりで、大まかながら、さっきよりは詳しく書いてみます。と言ってもさほどかわらないけど。
ご利用のソースがどのようなものなのかわからないので、うまく統合できるといいのですが。
恥ずかしながら、私は素人寄りなので、本来このような処理ですべきかどうかまったくわかりません。私はこんな感じで作った、と言うだけで。

//入力初期か?県選択か?確認か?
switch ($_SERVER["REQUEST_METHOD"]){
case "GET":
//入力初期
//県は選択されていないので、市のセレクトはとりあえず空
$si_option = "";
//処理モード:入力
$mode="input";
break;
case "POST":
switch ($_POST["submit_mode"]){
case "pos":
//その県の市リストを生成する
$si_option .= "<option>市の名前</option>";//のような感じでどんどん追加するループになると思う。
//処理モード:入力
$mode="input";
break;
default:
//確認処理-(1)
//処理モード:確認
$mode="check";
}
}

//処理モードによって分岐
switch ($mode){
case "input"://処理モード:入力
//県リストを生成する
$ken_option .= "<option>県の名前</option>";//のような感じでどんどん追加するループになると思う。選択されている県には selected を付ける。
//入力モードとしてのHTMLを展開
//その中で
//<input type="hidden" name="submit_mode">
//<select name="ken" onChange="select_pos()">{$ken_option}</select>
//<select name="si">{$si_option}</option>
//を出力
//すでに入力されている項目があれば $_POST で表示する
break;
case "check"://処理モード:確認
//確認処理に継続する処理や表示があればする
//ないか、あるいは、上の(1)で全て済ませて exit などしていれば不要
break;
}

function selest_pos(){
document.form.submit_mode.value= "pos";
document.form.submit();
}
※お礼文に書かれているJavaScriptの記述はこれだけでかまいませんが、functionのつづりが間違っています。

とりあえずこのような感じです。
ひとつの .php ファイルで処理する場合は、確認処理なのか入力中なのかを判断し、PHP の流れを制御してそれぞれの処理や表示をするようにすれば、今回のような submit での、市リストの表示し直しと確認処理が分岐できると思います。
うまくいかなかったらまた言ってください。

この回答への補足

詳しく教えて頂きありがとうございました。
今試しているところです。

購入したシステムが、PHPなのですが、htmlファイルを複数読み込んで構成させているので、組み立てるのにちょっと時間かかりそうです。

補足日時:2009/09/29 17:55
    • good
    • 0

確認のためのsubmitなのか、県を選択した時のsubmitなのか、


を判断できるようにしたらいいと思います。

私も似たような処理を作った事があるのですが、その時は、
まず、hiddenの項目(仮に submit_mode とする)を作っておいて、
県のセレクトで onChange="select_ken()" とかして、
select_ken() では、
document.form.submit_mode.value= "ken";
document.form.submit();
などとして、submitのモードを指定して送信しました。
で、再度そのページが表示される処理で、
switch ($_POST["submit_mode"]){
case "ken":
//その県の市のデータを読んで表示
break;
default:
//従来の確認処理
}
としています。
入力項目が消えてしまわないように、
他の項目を $_POST で再表示する必要があります。

この回答への補足

ありがとうございます。
今からやってみます!

補足日時:2009/09/29 10:08
    • good
    • 0
この回答へのお礼

2時間くらい格闘してみましたがうまくいきません。
知識不足が大きいのは解っていますが…
JSの記述が足りないのか、県を選択しても市の表記が変わらない状態に陥ってしまいました。
fanction selest_pos(){
document.form.submit_mode.value= "pos";
document.form.submit();
}
だけではやっぱり足りないですよね?・・・

>hiddenの項目(仮に submit_mode とする)を作っておいて、
とは、それ以下で説明されていることと考えてよろしいのでしょうか?

解らないことが多すぎて・・・
教えて頂けると嬉しい限りです。

お礼日時:2009/09/29 12:01

いまいちなにが起こっていて困っているのかよくわからないのですが


実はselectのoptionにselectedがないだけ だったりですか?

この回答への補足

至らない説明で申し訳ないです。

県を選択して、その県の市町村をSubmitさせてMySQLのDBから読み込ませる方法と取っています。

この方法を導入しているのが、登録画面のため、Submitさせると確認されてしまい、入力不備と判断されて他の項目が全部赤字で「入力されていません。きちんと入力して下さい。」みたいに出てしまうことに困っています。
また、一度Submitさせることによって画面が一番上に戻ってしまうことにも困っています。

今、Submitを分岐させることに挑戦していますが、うまくいきません…。
いい方法があれば教えて頂きたいです。

補足日時:2009/09/29 10:09
    • good
    • 0

自分はその手の処理の場合、ポップアップウィンドウをよく利用します。


ポップアップで子ウィンドウで県と市町村の選択画面を用意して
その値をJavaScriptで親ウィンドウに渡す。
ajaxなんかより手間はまったくかからないでできます。
で表示用に県と市町村の名前を表示して県と市町村のIDはhiddenタイプで隠しにしておいたフォームに渡す。
こんな感じの処理をやります。

または、入力画面そのものを一画面ではなくてウィザード形式の入力フォームにする。

またはajaxぽい動きになるけど実際にajaxすら使ってない方法としては
市町村名の部分はすべて読み込んでおいて単純に非表示にしておく。
それを選択された県に応じてJavaScriptで表示と非表示を切り替える処理をさせる。

この回答への補足

やっぱりajaxって難しいものなんですね。
似たようなサンプルがないかを探していたのですが、
購入したデーターの構造上 ID を付ける事が出来ないという欠点があり、中々使えそうな物が見つからない状態です。

tom233様が書かれている方法も考えては見ましたが出来ればソースをキレイにしておきたいので、その都度読み込みを行いたいのです。

初心者にはやっぱり難しいようですね。

HTMLとSCCくらいしかやって来なかったのでコレからどんどん勉強していかないと行けないと思っています。

なんかいいサンプルページでもご存知でしたら教えて頂きたいです。

補足日時:2009/09/28 16:11
    • good
    • 0

#1の回答に同意します。



が、どうしてもPHPでしたいのなら、
クッキーを使って
1回目のサブミットと、その後のサブミットの
処理を分岐する…というような方法も考えつきます。
    • good
    • 0

ajaxで処理するのが妥当です

この回答への補足

ご回答ありがとうございました。
ajaxという言葉を初めて聞いたのでちょっと調べてみます。

補足日時:2009/09/28 13:12
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!