我正在尝试利用jQuery UI(或任何其他对话框插件)来替换默认的Confirm对话框。 StackOverflow上有很多类似的问题和答案,例如:
jquery dialog: confirm the click on a submit button
然而,在ASP .NET中我需要更多东西。
由于页面上的一个表单约束,在ASP .NET页面上(使用ASP .NET 3.5)我可以有多个按钮提交相同的表单,并根据提交的标题信息< strong> Page 知道哪个控件(Button)触发了表单提交,并且可以在服务器上调用正确的方法(附加到Button的Click事件的方法)。
如果我使用其他StackOverflow答案的解决方案,例如:
buttons: {
'Delete all items': function() {
$(this).dialog('close');
currentForm.submit();
},
'Cancel': function() {
$(this).dialog('close');
}
}
在PostBack上不会调用任何事件处理程序。如果我将其替换为:
buttons: {
'Delete all items': function() {
$(this).dialog('close');
$buttonThatWasConfirmed.click();
},
'Cancel': function() {
$(this).dialog('close');
}
}
它将导致无休止的模态对话递归。如何在ASP .NET中解决它?
答案 0 :(得分:3)
作为一个选项:对于Button控件使用SubmitBehavior="false"
并在表单的结束标记之前放置脚本:
<script type="text/javascript">
var originalDoPostBack = __doPostBack;
__doPostBack = function (sender, args) {
$("#dialog").dialog({
modal: true,
title: "Confirm action",
buttons: {
Yes: function () {
$(this).dialog("close");
originalDoPostBack(sender, args);
},
Cancel: function () {
$(this).dialog("close");
}
}
});
};
</script>
如果您只想对特定按钮明确表示通话确认,可以使用下面的脚本(可以放在标题中)
function confirmPostBack(sender, args) {
$("#dialog").dialog({
modal: true,
title: "Confirm action",
buttons: {
Yes: function () {
$(this).dialog("close");
__doPostBack(sender.name, args || "");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
return false;
}
<asp:Button runat="server" Text="Click Me" OnClientClick="return confirmPostBack(this)" />
答案 1 :(得分:1)
我最近使用过这个,虽然它只适用于链接按钮。如果你愿意的话,你可以给它们设置样式(毕竟它们只是锚点)看起来像html按钮。
JS
$(function () {
$("#confirmMe").click(function (e) {
e.preventDefault();
var $anchor = $(this);
$("<div>Are you sure you want to do that?</div>").dialog({
title: "Confirm",
modal: true,
buttons: {
"Ok": function () {
window.location = $anchor.attr("href");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
});
});
.net标记(如果单击“确定”,将会引发confirmMe_Click事件)
<asp:LinkButton Text="Open Me" runat="server" ID="confirmMe"
ClientIDMode="Static" onclick="confirmMe_Click" />
答案 2 :(得分:1)
System.Web.UI.WebControls.LinkButton
并使用控件的PostbackEventReference来知道如果确认将提交哪个控件。如果您愿意,控件可以轻松地从System.Web.UI.WebControls.Button
继承。我选择使用链接按钮,因为它的操作非常类似于按钮Web控件,但不会发出<input type=submit>
,如果不使用控件适配器,则无法使用jQuery UI使用图标设置样式。
/// <summary>
/// A <see cref="T:System.Web.UI.WebControls.LinkButton"/> with added jQuery UI functionality to provide a modal dialog box to cancel the form submit client side.
/// </summary>
/// <remarks>This class requires the inclusion of jQueryUI</remarks>
[DefaultProperty("Text")]
[ToolboxData("<{0}:jQueryUIConfirmedLinkButton runat=\"server\"></{0}:jQueryUIConfirmedLinkButton>")]
public class jQueryUIConfirmedLinkButton : LinkButton
{
/// <summary>
/// Holds the postback event reference data so that the emitted client script can execute the postback if the user confirms the action.
/// </summary>
protected string eventReference = null;
/// <summary>
/// Gets or sets the emitted dialog's ID attribute.
/// </summary>
/// <value>
/// The dialog's ID attribute.
/// </value>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("dialog")]
[Localizable(true)]
public string DialogCssID
{
get
{
String s = (String)ViewState["DialogCssID"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["DialogCssID"] = value;
}
}
internal protected string DialogID
{
get
{
return String.Format("{0}_{1}", this.ClientID, DialogCssID);
}
}
/// <summary>
/// Gets or sets the content of the dialog. This can be plain text or HTML.
/// </summary>
/// <value>
/// The HTML or plain text content of the dialog.
/// </value>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("<p>Are you sure?</p>")]
[Localizable(true)]
public string DialogContent
{
get
{
String s = (String)ViewState["DialogContent"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["DialogContent"] = value;
}
}
/// <summary>
/// Gets or sets the title that will appear on the dialog.
/// </summary>
/// <value>
/// The dialog's title.
/// </value>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("Confirm Action")]
[Localizable(true)]
public string DialogTitle
{
get
{
String s = (String)ViewState["DialogTitle"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["DialogTitle"] = value;
}
}
/// <summary>
/// Gets or sets the text that will appear on the confirmation button.
/// </summary>
/// <value>
/// The text that will appear on dialog's confirmation button.
/// </value>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("Yes")]
[Localizable(true)]
public string DialogConfirmButtonText
{
get
{
String s = (String)ViewState["DialogConfirmButtonText"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["DialogConfirmButtonText"] = value;
}
}
/// <summary>
/// Gets or sets the text that will appear on the dialog's rejection button.
/// </summary>
/// <value>
/// The text that appears on the dialog's rejection button.
/// </value>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("No")]
[Localizable(true)]
public string DialogRejectButtonText
{
get
{
String s = (String)ViewState["DialogRejectButtonText"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["DialogRejectButtonText"] = value;
}
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Load" /> event. Emits the necessary client script for the control to function.
/// </summary>
/// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.eventReference = Page.ClientScript.GetPostBackEventReference(this, string.Empty);
Page.ClientScript.RegisterStartupScript(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogScript"), this.GetClientScript(), true);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), string.Format("{0}{1}", this.ClientID, "-DialogShowScript"), string.Format("function {0}Confirm() {{$('#{0}').dialog('open');}}", this.DialogID), true);
this.OnClientClick = String.Format("{0}Confirm();return false;", this.DialogID);
}
/// <summary>
/// Renders the contents of the control to the specified writer. Adds the dialog HTML container to the output stream.
/// </summary>
/// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter" /> object that represents the output stream to render HTML content on the client.</param>
protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
writer.AddAttribute("id", this.DialogID);
writer.RenderBeginTag("div");
writer.Write(this.DialogContent);
writer.RenderEndTag();
}
public override void RenderEndTag(HtmlTextWriter writer)
{
base.RenderEndTag(writer);
}
/// <summary>
/// Gets the client script.
/// </summary>
/// <returns>A string that will be output to the client as script</returns>
private string GetClientScript()
{
return string.Format(@"$(function () {{
$('#{0}').dialog({{
autoOpen: false,
modal: true,
resizable: false,
buttons: {{
'{1}': function () {{
$(this).dialog('close');
eval({2});
}},
'{3}': function () {{
$(this).dialog('close');
}}
}},
title: '{4}'
}});
}});", this.DialogID, this.DialogConfirmButtonText, this.eventReference, this.DialogRejectButtonText, this.DialogTitle);
}
}
答案 3 :(得分:0)
我在一段时间后想出了这项工作,所以不确定它是否仍然是最新的jquery-ui对话框插件,但你得到了一般的想法。它(不幸)使用eval
来执行javascript asp.net生成以提交放置在锚点href中的表单。您只需要为锚定{c}类confirm-required
。
<div class="confirm-dialog ui-helper-hidden" title="Confirm">
<span class="ui-icon ui-icon-alert"></span>
<p>Are you sure?</p>
</div>
<script language="javascript" type="text/javascript">
$(function(){
// call confirm dialog boxes from buttons that require it
$(".confirm-required:isactive").click(function () {
var callback = $(this).attr("href");
return showConfirmDialog(callback);
});
});
this.showConfirmDialog = function (callback) {
$(".confirm-dialog").dialog("destroy");
$(".confirm-dialog").dialog({
autoOpen: true,
modal: true,
buttons: {
"OK": function () {
$(this).dialog("close");
eval(callback);
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
return false;
};
</script>
答案 4 :(得分:0)
我承认它有点冗长,但以下是我能想到的每个案例的作品:
$(document).ready(function () {
'use strict';
var getParsedPostback = function getParsedPostback(self) {
/*
* self is a jQuery object. The purpose of this function is to extract the
* __doPostBack function or the WebForm_DoPostBackWithOptions function as a
* string, parse out the component arguments, and return it as a different
* function to be used as a callback. If the postback function does not exist
* as a string (in the case of a submit button, for instance) then the
* returned callback should unbind any click handlers and then trigger the
* element's click event.
*/
var postback = self.data('postback'),
trimLeft = /^\s+/,
trimRight = /\s+$/,
startingQuote = /^['"]/,
endingQuote = /['"]$/,
eventTarget,
eventArgument,
validation,
validationGroup,
actionUrl,
trackFocus,
clientSubmit;
if (postback.substring(postback.length - 1, postback.length) === ';') {
//remove the trailing ";"
postback = postback.substring(0, postback.length - 1);
}
if (postback.indexOf('javascript:') === 0) {
//remove the "javascript:"
postback = postback.substring(('javascript:').length, postback.length - 1);
}
//in case postback is in the form __doPostBack('XXXXXX','XXXXXX')
postback = decodeURIComponent(postback);
//parse by case
if (postback.indexOf('__doPostBack(') === 0) {
//postback should now be __doPostBack('XXXXXX','XXXXXX')
postback = postback.substring(('__doPostBack(').length, postback.length - 2);
postback = postback.split(',');
eventTarget = encodeURIComponent(postback[0].replace(startingQuote, '').replace(endingQuote, ''));
eventArgument = encodeURIComponent(postback[1].replace(startingQuote, '').replace(endingQuote, ''));
postback = function () {
__doPostBack(eventTarget, eventArgument);
};
} else if (postback.indexOf('WebForm_DoPostBackWithOptions(') === 0) {
//postback should now be WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX', 'XXXXXX'))
postback = postback.substring(('WebForm_DoPostBackWithOptions(').length, postback.length - 2);
postback = postback.split(',');
eventTarget = encodeURIComponent(postback[0].replace(startingQuote, '').replace(endingQuote, ''));
eventArgument = encodeURIComponent(postback[1].replace(startingQuote, '').replace(endingQuote, ''));
validation = !!postback[2].replace(startingQuote, '').replace(endingQuote, ''); //use !! to convert string to boolean
validationGroup = encodeURIComponent(postback[3].replace(startingQuote, '').replace(endingQuote, ''));
actionUrl = encodeURIComponent(postback[4].replace(startingQuote, '').replace(endingQuote, ''));
trackFocus = !!postback[5].replace(startingQuote, '').replace(endingQuote, ''); //use !! to convert string to boolean
clientSubmit = !!postback[6].replace(startingQuote, '').replace(endingQuote, ''); //use !! to convert string to boolean
postback = function () {
__doPostBack(new WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit));
};
} else if (postback === 'submit') {
//no apparent postback handler, must be a submit or an image
postback = function () {
//unbind the assigned click handler
self.unbind('click');
//trigger the click event
self.click();
};
}
return postback;
};
var clickHandler = function clickHandler(e) {
var postback = getParsedPostback($(this)); //get the postback as a callback
$('div#dialog').dialog('option', {
"buttons": {
"Delete all items": function () {
$(this).dialog('close');
postback(); //call the postback
},
"Cancel": function () {
$(this).dialog('close');
}
}
}).dialog('open');
e.preventDefault();
return false;
};
var storePostbacks = function storePostbacks() {
/*
* The purpose of this function is to remove any existing __doPostBack functions
* or WebForm_DoPostBackWithOptions functions and store them in the "data" for
* the element. The "getParsedPostback" function above wil make extensive use of
* the element's "data" to parse a usable callback for postback.
*/
$('input[type="submit"], input[type="button"], input[type="image"], a[href*="__doPostBack"]').each(function (i, elem) {
var self = $(elem),
postback = '';
if (typeof self.attr('onclick') !== 'undefined') {
//store the postback in data and remove from the element.
postback = self.attr('onclick');
self.removeAttr('onclick').data('postback', postback);
} else if (typeof self.attr('href') !== 'undefined') {
//store the postback in data and remove from the element.
postback = self.attr('href');
self.attr('href', '#').data('postback', postback);
} else if (self.attr('type') === 'submit' || self.attr('type') === 'image') {
//flag as a submit.
self.data('postback', 'submit');
}
});
};
storePostbacks();
$('input#<%#aspButton1.ClientID %>').click(clickHandler);
$('input#<%#aspButton2.ClientID %>').click(clickHandler);
$('input#<%#aspImageButton.ClientID %>').click(clickHandler);
$('a#<%#aspLinkButton.ClientID %>').click(clickHandler);
$('div#dialog').dialog({
"autoOpen": false
});
});
使用带有jQuery 1.8.2和jQueryUI 1.9.0的ASP.Net 4.0 Framework测试以下标记:
<body>
<form id="form1" runat="server">
<div>
<div id="dialog">
<p>Test of dialog.</p>
</div>
<div id="controls">
<asp:Button ID="aspButton1" runat="server" Text="aspButton1" />
<asp:LinkButton ID="aspLinkButton" runat="server">LinkButton</asp:LinkButton>
<asp:ImageButton ID="aspImageButton" runat="server" />
<asp:Button ID="aspButton2" runat="server" Text="aspButton2" />
</div>
</div>
</form>
</body>
答案 5 :(得分:0)
这是我的两分钱,对我的项目有用:
// Initialices the behaviour when the page is ready
$(function() {
// Sets the function to be called when the confirmation button is pressed
$('.jqConfirmacionBorrar').click(function(e) {
// Prevents the default behaviour of the button
e.preventDefault();
// Gets the name of the button that was clicked
var ControlClickedName = $(this).attr('name');
// Sets up the dialog to be called, with some custom parameters.
// The important one is to do the postback call when the confirmation
// button ('Aceptar' in spanish) is clicked.
$("#DivConfirmacion").dialog({
width: 650,
modal: true,
draggable: true,
autoOpen: false,
buttons: {
'Cancelar': function() {
$(this).dialog('close');
return false;
},
'Aceptar': function() {
$(this).dialog('close');
__doPostBack(ControlClickedName, '');
return true;
}
}
});
// Opens the dialog to propt the user for confirmation
$('#DivConfirmacion').dialog('open');
});
});