- 締切済み
<input type="file">タグで「キャンセル」か「開く」を取得したい
いつもお世話になります。 <input type="file">タグで、 ファイル選択ダイアログを開いたあとに、 「キャンセル」を押したのか、 ファイルを選択したのか(「開く」を押したのか)を 取得する方法はないのでしょうか? よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- koutarou504
- ベストアンサー率44% (182/407)
一応、「仕様」にバグがある可能性もあるという意識も持っておいた方が良いと思います。 なにしろ、クリアはA側のみの仕様,ダイアログの結果は拾えない仕様,ダイアログの結果に関わらずBに残っている情報をAに設定する仕様。 ・・・、仕様バグの様な気がぁ~。 >oCtlFile.click()は、 ><input type="file">で表示される「参照...」をクリックしたイベントを起こしています。 そのクリックイベントでなんらかの処理が記述されている訳ですよね? その処理がダイアログを開いている事だと思うのですが、そこでダイアログの戻り値を拾わない事にはダイアログに複数ボタンがあるとしても処理として不自然ですが・・・。 なんとか拾って、せめて変数にでも残して、後にその変数にて判断できる様にしたい処ですが・・・。 つまり、ダイアログの結果にて処理を分岐させる(常にBの内容をAに設定する事をやめる)か、クリアでA,B共に行うかのどちらかでしょう・・・。 サーバ側で問題ないのなら、スクリプトでもBのクリアは可能だと思いますが・・・。そうでないと見かけ上の意識と実際の結果がずれてしまうと思いますが・・・。 尚、上記で対応できない場合は、「これは出来ません。」という前提で「これが出来る方法はありませんか?」と聞いている様な事になりますが・・・。 わたし(プログラマ)としては設計からおかしい様に感じ、元から設計しなおすべきと感じます。
- koutarou504
- ベストアンサー率44% (182/407)
そもそも、「ファイル選択ダイアログ」を開く処理って??? ダイアログに「開く」と「キャンセル」と複数のボタンがあるのなら、それを表す戻り値があると思われますが・・・。MsgBox 関数だってそれなりに戻り値はあるし・・・。 (自作であり、かつ戻り値がなければそれがそもそもの問題かと・・・。) >★キャンセルしたが、 >前回値がBのfileタグに残ってしまっているので、 >Aの見かけ上のtextに反映されてしまう。 それが問題なら、Aのクリアの時点でBのfileタグの値をクリアするべきでしょう。つまり意識としてAのtextはBのfileタグの値と一緒という設計になっている様なので。 とはいえ、oCtlFile.click() がなんだか判らないのでどうしようもないかと・・・。 (というか、これによって動作している処理自体が不明。クリックイベントのきっかけとしてなのでしょうが、そのクリックイベントでどの様な処理が記述されているのか?) ところで、初回にいきなりキャンセルで戻った場合は、問題ないのでしょうか?
補足
>oCtlFile.click() がなんだか判らないのでどうしようもないかと・ oCtlFileは、<input type="file">コントロールオブジェクトです。 oCtlFile.click()は、 <input type="file">で表示される「参照...」をクリックしたイベントを起こしています。 >ダイアログに「開く」と「キャンセル」と複数のボタンがあるのなら、それを表す戻り値があると思われますが・・・ ためしに、 Dim xxx xxx = oCtlFile.click() として戻り値が拾えるか試してみましたが、 「開く」にしろ「キャンセル」にしろ xxxはEmpty値でした。 戻り値は拾えないようです。 >ところで、初回にいきなりキャンセルで戻った場合は、問題ないのでしょうか? 初回の場合は、Bフレームのfileタグには 何も指定されていないので、問題ないです。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
私も、#2の方が言われているように、 fileタグをフォームでくくって、クリアのタイミングでリセットするのが簡単だと思います。 キャンセルしたのかどうかの判断ですけど、 キャンセルした場合、 ファイルタグの内容(value)は、""のままであるか前回のままであるわけですから、 前回の内容というのを適当なフィールドにとっておけばいいと思います。 (結局、見かけ上のファイル(A)が""になっても(Bで)送信されてしまうのでBをリセットすることが必要だと思われますが・)
補足
#2の方への補足の通り、 BフレームのリセットはNGです。 >(結局、見かけ上のファイル(A)が""になっても(Bで)送信されてしまうのでBをリセットすることが必要だと思われますが・) Bのファイルは送信されてしまいますが、 サーバーでの判断として、 Aの見かけ上のファイルが""であれば、 Bのファイルは保存しないようにしています。
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 VBScriptはあまり使ったこと無いので的外してるかもしれませんが、 Aのtextをクリアボタンでクリアするオペレーションで Bフレームのフォームもリセットかけるのじゃだめでしょうか。 他にクリアしたくない物があるとすると難しいかもしれませんが。
補足
Bフレームのリセットも当然考えましたが、 アップロードするファイルは複数(5つまで)指定できますので、 Aフレームの「クリア」ボタンをクリックで Bフレームのリセットは難しいです。 (Aフレームの「クリア」ボタンは一つのファイル指定をクリアする仕様なので・・・)
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 直接取得する方法は無いと思います。 擬似的にJavaScriptで可能かもしれませんが、完全なものは出来ないような気がします。 ちなみに、キャンセルまたは開くを押したのを使用する目的はなんでしょうか? それにより代替案があるかもしれません。
補足
やはりムリでしょうか。 キャンセルまたは開くを押したのを使用する目的は、 少し長くなってしまいますが、以下のとおりです。 メインフレーム(A)と隠しフレーム(B)があり、 実際のfileタグはBにあります。 サーバーへのデータ転送は 全てBフレームで行う、という規約があるため、 Bにfileタグをおいています。 ただ、Aにも見かけ上のため、 textタグと「参照」ボタン、 及び取消のための「クリア」ボタンを 置いています。 現在ファイルの選択方法は、 BのfileタグをAの「参照」ボタンイベントのVBscriptで Bのfileタグのclick()イベントを起こして ダイアログを開いています。 ファイル選択ダイアログでファイルを選択後、 Aの見かけ上のtextにパスを反映するような スクリプトになっています。 (以下のようなスクリプトです) 【Aのスクリプト(「参照」ボタンのonclickイベントで動く】 Sub fileUpd_onclick(Byval sNo) Dim oCtlFile Dim oCtlDummy set oCtlFile = Bフレーム.document.getElementById("filUldFile" & sNo) set oCtlDummy = document.getElementById("txtDummyFile" & sNo) oCtlFile.click() Call Bフレーム.SetFileValue(CInt(sNo)) oCtlDummy.value = Bフレーム.m_vTmpFileNameArr(CInt(sNo)-1) End Sub 【Aのスクリプト(「クリア」ボタンのonclickイベントで動く】 Sub fileCls_onclick(Byval sNo) document.getElementById("txtDummyFile" & sNo).value = "" Bフレーム.m_vTmpFileNameArr(CInt(sNo)-1) = "" End Sub 【Bのスクリプト】 Public m_vTmpFileNameArr(4) sub SetFileValue(Byval nFileNo) m_vTmpFileNameArr(nFileNo-1) = document.getElementById("filUldFile" & nFileNo).value end sub 上記のスクリプトでは、 以下のようなオペレーションで問題がおきてしまいます。 1.Aの「参照」ボタンでファイルを選択。 2.Aの見かけ上のtextをクリアボタンでクリアする。 3.もう一度Aの「参照」ボタンをクリックするが、 キャンセルで取り消す。 ★キャンセルしたが、 前回値がBのfileタグに残ってしまっているので、 Aの見かけ上のtextに反映されてしまう。 そこで、ファイル選択ダイアログのキャンセルが取れれば、 Aの見かけ上のtextには空文字を入れるように できるかな・・・と思った次第であります。 大変長くなってしまい、申し訳ないのですがが、 イメージして頂けますでしょうか? 何かアイデアがあれば、ご教授ください。 よろしくお願いします。
お礼
やはり「開く」or「キャンセル」を拾うのはムリっぽいので、クリアボタンをなくすように仕様変更をして対応しました。 みなさん、アドバイスありがとうございました。