ここでは ASP.NET の Web アプリケーションで Windows フォームアプリケーションのようなメッセージボックス制御を行うサンプルを掲載しています。
スポンサーリンク
ここで説明するメッセージボックスの制御には、Javascript を使用してポストバックを行っています。Javascript からフォームに対してサブミット ( ポストバック ) しているだけですので技術的に難しいことはありません。
今回は、以下のような一般的(?)な状況を例に考えることとします。
- 複数の入力項目を持つWebフォームで登録ボタンクリックでデータベースへ登録する
- 入力された情報がデータベース上に存在しない場合はそのまま登録する
- 入力された情報が既にデータベース上に存在すれば確認ダイアログを表示する
- OKボタンがクリックされた場合にのみ、その情報を上書きし、キャンセルボタンの場合は何もしない
Windows アプリケーションでは容易ですが、ASP.NET のような Web アプリではサーバとブラウザでそれぞれ実行順序を制御する必要があるので、悩むことも多いです。
[ ポイント ]
- データベースへの問い合わせはWebサーバで行う
- 確認ダイアログはブラウザ上で出力させる
- JavaScript からポストバックを行う
メッセージボックス制御サンプル(枠組のみ)
メッセージボックス制御のサンプルコードになります。なお、データベースへの登録処理などは本題ではありませんので記述していません。詳細はサンプルコード中のコメントを参照ください。
ASPX
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
</form>
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then
'Javascriptからのsubmitはポストバックとして認識される
' 上書きする(OK)ボタンがクリックされた場合
Dim update As String = Page.Request.QueryString.Get("update")
If (update = "true") Then
'----------------------------------------------
' TODO:ここで、データを上書きする処理を行う
'----------------------------------------------
'(後始末)
' 次のポストバックでこのルートを通らないようにするために
' アップデートのために追加したGET パラメータ(update)をaction属性から除去する
Dim formid As String = Me.Form.ClientID
Dim cScript As String = formid + ".action = ""Default.aspx"";"
'JavaScriptの埋め込み(画面表示前に実行させる)
ClientScript.RegisterClientScriptBlock(Me.GetType(), "clientscript", cScript, True)
End If
End If
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim confirm As Boolean
'--------------------------------------------------------
' TODO:ここにデータベースに存在するか確認する処理を記述する
'--------------------------------------------------------
If (True) Then
' 確認ダイアログを出力させる
confirm = True
Else
'確認ダイアログを出力させない
confirm = False
End If
'マスターページを使っている場合、formタグのidがaspnetFormとなるので、
'確実に取得するためには、Form.ClientIDプロパティからIDを取得する
Dim formid As String = Me.Form.ClientID
If (confirm) Then
' 確認ダイアログを出力するスクリプト
' POST先は自分自身(Default.aspx)
Dim sScript As String = "if(confirm(""上書きしますか?"")){ " + _
formid + ".method = ""post"";" + _
formid + ".action = ""Default.aspx?update=true"";" + _
formid + ".submit();" + _
"}"
'JavaScriptの埋め込み
ClientScript.RegisterStartupScript(Me.GetType(), "startup", sScript, True)
' ClientScript.RegisterStartupScriptメソッドで登録した場合、ブラウザでの描画完了後に
' 登録したJavaScriptが実行される
'
' ここでは、OKボタンが押されたことをGETパラメーター(update)で通知する
Else
'--------------------------------------------------------
' TODO:ここに、データを登録する処理を記述する
'--------------------------------------------------------
End If
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
// Javascriptからのsubmitはポストバックとして認識される
// ここで、GETパラメーター(update)がTrueの場合には、フォーム上のデータを
// データベース上に上書きする処理を記述する
// 上書きする(OK)ボタンがクリックされた場合
string update = Page.Request.QueryString.Get("update");
if (update == "true") {
//-------------------------------------------------
// TODO:ここで、データを上書きする処理を行う
//-------------------------------------------------
//(後始末)
// 次のポストバックでこのルートを通らないようにするために
// アップデートのために追加したGET パラメータ(update)をaction属性から除去する
string formid = this.Form.ClientID;
string cScript = formid + ".action = \"Default.aspx\";";
// JavaScriptの埋め込み(画面表示前に実行させる)
ClientScript.RegisterClientScriptBlock(this.GetType(), "clientscript", cScript, true);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Boolean confirm;
//-------------------------------------------------
// TODO:ここにデータベースに存在するか確認する処理を記述する
//-------------------------------------------------
if (true) {
// 確認ダイアログを出力させる
confirm = true;
} else {
// 確認ダイアログを出力させない
confirm = false;
}
// マスターページを使っている場合、formタグのidがaspnetFormとなるので、
// 確実に取得するためには、Form.ClientIDプロパティからIDを取得する
string formid = this.Form.ClientID;
if (confirm) {
// 確認ダイアログを出力するスクリプト
string sScript = "if(confirm(\"上書きしますか?\")){ " +
formid + ".method = \"post\";" +
formid + ".action = \"Default.aspx?update=true\";" +
formid + ".submit();" +
"}else{" +
"" +
"}";
// JavaScriptの埋め込み
ClientScript.RegisterStartupScript(this.GetType(), "startup", sScript, true);
// ClientScript.RegisterStartupScriptメソッドで登録した場合、ブラウザでの描画完了後に
// 登録したJavaScriptが実行される
//
// OKがクリックされるとGETパラメーター(update)を付けて、ポストバックする
} else {
//-------------------------------------------------
// TODO:ここに、データを登録する処理を記述する
//-------------------------------------------------
}
}
F5 などで再表示を行った場合の問題点
今回のサンプルでは上書きするかの判断を GET パラメータ ( update ) で行っていますが、 Page_Load イベントで上書き処理を行った状態で再表示 ( F5 ) を行うと、再度上書き処理が行われてしまいます ( GET パラメーターも再度送られる )。
対応方法は色々あると思いますが、解決手段の1つとして、Page_Load イベントで更新登録したあとでClientScript.RegisterClientScriptBlock で スクリプトを埋め込む代わりに、Response.Redirect ( URL には Get パラメーターをつけない ) で自分自身にリダイレクトさせる方法があります。クライアントとブラウザ間でやり取りの回数が増えますが、簡単な対処方法です。
ポストバックにしたくないとき
今回は Javascript からポストバックするようにしましたが、” キャンセル ” が選択されたときに、単にページ遷移する場合には form.submit ではなく、location.href を使用できます。
location.href = “Default.aspx”;
ASP.NET とは関係なく、Javascript の話です