SimpleModal が ASP.Net ポストバックを破壊する
-
09-06-2019 - |
質問
使っています jQuery そして シンプルモーダル ASP.Net プロジェクトで Web アプリ用の素敵なダイアログを作成します。残念ながら、モーダル ダイアログ内のボタンはポストバックを実行できなくなり、これは実際には許容できません。
私が見つけたソースが 1 つあります 回避策, 、しかし、私は一生それを機能させることができません、主に必要な手順をすべて完全に理解していないためです。
ポストバックを置き換えるという回避策もありますが、それは見苦しく、おそらく最も信頼できるものではありません。ポストバックをもう一度機能させたいと思っています。何か案は?
アップデート:明確にしておきたいのですが、ポストバックの実行に使用される Javascript が何らかの形で壊れているため、ポストバックが機能していません。そのため、ボタンをクリックしても何も起こりません。
解決
お二人とも正しい道を歩んでました。私が気づいたのは、SimpleModal が ASP.Net の外側にある本文にダイアログを追加しているということです。 <form>
, 要素が見つからないため、機能が中断されます。
それを修正するために、SimpleModal ソースを変更してすべてを追加しました。 'form'
の代わりに 'body'
. 。ダイアログを作成するときは、 persist: true
ボタンが開閉しても確実に留まるようにするためのオプションです。
皆さん、提案してくれてありがとう!
アップデート: バージョン 1.3 では、 appendTo
モーダル ダイアログを追加する要素を指定するための設定内のオプション。 ここにドキュメントがあります.
他のヒント
すべての標準 ASP.NET ポストバックは、ページ上で __doPostBack JavaScript メソッドを呼び出すことで機能します。この関数はフォーム (ASP.NET が実際に好むのは 1 ページにつき 1 つのフォームだけです) を送信します。このフォームには、すべてのビューステートとその他の機能が存在する非表示の入力フィールドが含まれています。
一見すると、モーダルのコンテンツがたまたま HTTP GET から ASP.NET ページに送信されたものでない限り、SimpalModal にはページのフォームや標準の隠し入力を台無しにするものは何もありません。その結果、2 つの ASP.NET フォームが 1 つの DOM にレンダリングされ、ほぼ確実に __doPostBack 関数が台無しになります。
の使用を検討しましたか? ASP.NET AJAX ModalPopup コントロール?
Web ブラウザは、無効または非表示のフォーム要素を POST しません。
つまり、何が起こっているのかというと、次のとおりです。
- ユーザーがダイアログ内のボタンをクリックします。
- ボタンは SimpleModal の close() メソッドを呼び出し、ダイアログとボタンを非表示にします。
- クライアントはフォームを POST します (ボタンの ID なし)。
- ASP.NET フレームワークは、どのボタンがクリックされたかを認識できません
- サーバー側のコードは実行されません。
解決策は、クライアント上で必要なことをすべて実行し (この場合はダイアログを閉じます)、その後自分で __doPostback() を呼び出すことです。
次に例を示します (「dlg」はクライアント側の SimpleModal ダイアログ参照です)。
btn.OnClientClick = string.Format("{0}; dlg.close();",
ClientScript.GetPostBackEventReference(btn, null));
これにより、ダイアログが非表示になり、フォームが送信され、そのボタンに対して用意されているサーバー側イベントが呼び出されます。
@ダン
すべての標準 ASP.NET ポストバックは、ページ上で __doPostBack JavaScript メソッドを呼び出すことで機能します。
HTML 入力コントロールがすでにフォームを送信しているため、asp:Buttons は __doPostback() を呼び出しません。
これに気付かされました - tghw と、本体修正の代わりにフォームを追加した他のすべての貢献者に感謝します。(1.3 バージョンでは属性によって解決されました)
ところで:.net からプログラムでダイアログを閉じる必要がある場合は、このタイプの構文を使用できます。
private void CloseDialog()
{
string script = string.Format(@"closeDialog()");
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), UniqueID, script, true);
}
Closeddialog の JavaScript は次のようになります...
function closeDialog() {
$.modal.close();
}
simplemodal.js を変更しなくても、次の機能が動作することがわかりました。
function modalShow(dialog) {
// if the user clicks "Save" in dialog
dialog.data.find('#ButtonSave').click(function(ev) {
ev.preventDefault();
//Perfom validation
// close the dialog
$.modal.close();
//Fire the click event of the hidden button to cause a postback
dialog.data.find('#ButtonSaveTask').click();
});
dialog.data.find("#ButtonCancel").click(function(ev) {
ev.preventDefault();
$.modal.close();
});
}
したがって、ダイアログ内のボタンを使用してポストバックを発生させる代わりに、その送信を阻止してから、フォーム内の非表示のボタンを見つけて、そのクリック イベントを呼び出します。
FWIW、更新しました あなたが指摘したブログ投稿 説明とともにここに再投稿します。推論とその他の詳細はブログ投稿にあります。
解決策(昼食前に最後にチェックインした時点):
- ダイアログの onClose イベントをオーバーライドし、次の操作を実行します。
- ダイアログのデフォルトの Close 関数を呼び出します。
- ダイアログ div の innerHTML を単一に設定します。
- __doPostBack をハイジャックし、新しい関数 newDoPostBack を指定します。
ウェブ上で見たいくつかのコメントによると、ポイント 1 についてはもう少し説明が必要です。残念ながら、私はもう同じ雇用主ではないので、使用したコードにアクセスすることはできませんが、できる限りのことは行います。まず、次のように新しい関数を定義し、ダイアログがその関数を指すようにすることで、ダイアログの onClose 関数をオーバーライドする必要があります。
$('#myJQselector').modal({onClose: mynewClose});
- ダイアログのデフォルトの Close 関数を呼び出します。定義した関数では、まずデフォルトの機能を呼び出す必要があります (通常オーバーライドするほぼすべてのものに対するベスト プラクティス)。
- ダイアログ div の innerHTML を単一に設定します。– これは必須の手順ではないため、理解できない場合はスキップしてください。
- __doPostBack をハイジャックし、新しい関数 newDoPostBack を指定します。
function myNewClose (dialog)
{
dialog.close();
__doPostBack = newDoPostBack;
}
- newDoPostBack 関数を作成します。
function newDoPostBack(eventTarget, eventArgument) {var theForm = document.forms[0];if (!theForm){theForm = document.aspnetForm;}if (!theForm.onsubmit || (theForm.onsubmit() != false)){document.getElementById("__EVENTTARGET").value = eventTarget;document.getElementById("__EVENTARGUMENT").value = eventArgument;theForm.submit();} }
新しい Jquery.simplemodal-1.3.js には、appendTo と呼ばれるオプションがあります。したがって、デフォルトは appendTo:'body' であるため、appendTo:'form' というオプションを追加します。これは asp.net では機能しません。
同じ問題がありましたが、 {appendTo:'form'}
モーダルポップアップが完全に間違ってレンダリングされました(CSSの問題があるかのように)。
私が構築しているテンプレートには、ページ上に他のフォームを配置するインクルードが含まれていることがわかりました。設定したら {appendTo:'#aspnetForm'}
(デフォルトの Asp.net フォーム ID)、すべてがうまく機能しました (ポストバックを含む)。
tghw の回答に加えて、この優れたブログ投稿が役に立ちました。 jQuery:モーダルフォームのポストバックを修正する -- 特に BtnMike のコメント:「また、cssclass =「simplemodal-close」をASP:ボタンに設定してはいけません。」クラスからそれを脱ぐことは、私から啓発的ではないソリューションでした。
-ジョン
SimpleModal ソースを変更したくない場合。これを試して..
modal() メソッドを呼び出した後、これを追加します。
$("#simplemodal-overlay").appendTo('form');
$("#simplemodal-container").appendTo('form');
SimpleModal プラグインは、これをマークアップに 2 つ追加します。
- 背景の「simplemodal-overlay」
- 「simplemodal-container」には、ポップアップモーダルとして必要な div が含まれています。