[英]Problem with SweetAlert Confirmation not flowing to server side procedure using asp.net button
希望有人能帮助我理解.. 我有一个 asp.net 项目,我决定使用 SweetAlert 作为确认按钮。 我在这里遵循了建议:
使用 SweetAlert2 替换 ASP.Net 按钮上的“return confirm()”
问题是虽然 SweetAlert 提示工作正常,但在接受时,服务器端代码没有被执行。
<script src="Scripts/sweetalert-dev.js"></script>
<link href="Styles/sweetalert.css" rel="stylesheet" />
这是按钮:
<asp:Button ID="btndiscard" runat="server" Font-Size="Large" Text="Discard" Width="100px" onClientClick="return fnConfirmDiscard(this);" OnClick="btndiscard_Click" ToolTip="Discard this application (must be pending)"/>
这是 javascript 代码:
<script type="text/javascript">
var myok = false
function fnConfirmDiscard(btndiscard) {
//return confirm("Confirm to discard this application");
if (btndiscard.dataset.confirmed) {
// The action was already confirmed by the user, proceed with server event
btndiscard.dataset.confirmed = false;
alert("true");
return true;
} else {
// Ask the user to confirm/cancel the action
event.preventDefault();
swal({
title: 'Are you sure?',
text: "You won't be able to revert this!",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then(function(myresult) {
// Set data-confirmed attribute to indicate that the action was confirmed
if (myresult) {
btndiscard.dataset.confirmed = true;
alert("test then");
// Trigger button click programmatically
btndiscard.click();
}
}).catch(function (reason) {
// The action was canceled by the user
alert("test catch");
});
}
}
这是服务器端代码隐藏:
protected void btndiscard_Click(object sender, EventArgs e)
{
// this procedure will discard a credit application (change status to "X")
// ask for confirmation
bool wasposted = false;
try
{
System.Data.SqlClient.SqlCommand qryproc;
string CAccountsConnection = System.Configuration.ConfigurationManager.ConnectionStrings["CAConnectionString"].ConnectionString;
string entid = ("00000" + lblentid.Text.Trim());
qryproc = new System.Data.SqlClient.SqlCommand("exec sp_CAChangeStatus @entid,@newstatus");
qryproc.Parameters.Add("@entid", SqlDbType.Char, 11);
qryproc.Parameters.Add("@newstatus", SqlDbType.Char, 1);
qryproc.Parameters["@entid"].Value = entid;
qryproc.Parameters["@newstatus"].Value = "X";
qryproc.Connection = new System.Data.SqlClient.SqlConnection(CAccountsConnection);
qryproc.Connection.Open();
qryproc.ExecuteNonQuery();
wasposted = true;
qryproc.Connection.Close();
qryproc.Dispose();
wasposted = true;
}
catch
{
wasposted = false;
}
if (wasposted)
{
lblcurrstatus.Text = "D";
MessageToUser("Transaction successfull, application discarted.",MessageTypes.result_ok);
ResetAllFields();
lblentid.Text = "";
btnnewpage.Text = "New";
MultiView1.ActiveViewIndex = 0;
}
else
MessageToUser("Transaction not successfull! please try again.",MessageTypes.error);
}
在使用 sweetalert 之前,我使用的是一个简单的 javascript 确认框,它工作正常,服务器端程序运行也没有问题。
如果我删除 event.preventDefault() 然后调用服务器端过程但是 sweetalert 取消也不起作用(无论如何执行服务器端代码)
有人见过这个问题吗? 任何帮助将不胜感激,谢谢。
感谢 Albert D 对问题的出色解释。 查看答案后,我注意到我的 Swal Function 中使用的参数与您的代码不符。 我更改了这些参数,但仍然无法正常工作。 我验证了我的源 javascritpt 文件,问题基本上是我使用的是 bootstrap,并且为该作业引用了错误的文件。
所以不要使用:
<script src="Scripts/sweetalert-dev.js"></script>
我改为(从https://www.cdnpkg.com/bootstrap-sweetalert/file/sweetalert.min.js/下载后):
<script src="Scripts/sweetalert.min.js"></script>
最后,在进行了建议的调整后,结果如下:
<script type="text/javascript">
function fnConfirmDiscard(btndiscard) {
//return confirm("Confirm to discard this application");
// if no account has been created dont do anything...
if (document.getElementById("lblentid").innerHTML.trim() == "")
return false;
if (btndiscard.dataset.confirmed) {
// The action was already confirmed by the user, proceed with server event
btndiscard.dataset.confirmed = false;
return true;
} else {
// Ask the user to confirm/cancel the action
event.preventDefault();
swal({
title: "Are you sure you wish to discard application?",
text: "You will not be able to change this!",
icon: "warning",
buttons: ["Cancel","Continue"],
dangerMode:true,
}).then(function(myresult) {
// Set data-confirmed attribute to indicate that the action was confirmed
if (myresult) {
btndiscard.dataset.confirmed = true;
// Trigger button click programmatically
btndiscard.click();
}
}).catch(function (reason) {
// The action was canceled by the user
});
}
}
现在它按预期工作。 再次感谢。
嗯,一个简单的 js 符合工作,因为警报,并确认 HALTS 代码。
然而,如今,每个 js 例程都不会停止代码。 因此,当您单击该按钮时,您运行的 js function 不会等待。 我再重复一遍:
js例程不等待!!!!
但是它会运行,弹出甜蜜的警报,那一点 true/false 值将返回到按钮单击事件。 因此,您的对话框显示,但按钮事件也会触发。
因此,您可以使用一些技巧来解决此问题。 如前所述,您的 js 代码中需要一个公共(全局)标志 var,我看到您确实有这个:
var myok = false
function fnConfirmDiscard(btndiscard) {
//return confirm("Confirm to discard this application");
if (btndiscard.dataset.confirmed) {
因此,在页面加载时设置 var myok = false - 这仅在每次页面加载(或回发)时设置第一次。
所以,我们必须让你的日常工作是这样的:
您单击按钮,显示对话框,我们必须重复,必须向该按钮的 onclient 单击例程返回 false。 现在显示甜蜜的对话框,function 已经运行 - 并且不会停止。!! 它正确地运行到 function 和代码的最后一行。
您需要的代码应该如下所示:
<script type="text/javascript">
var myok = false
function fnConfirmDiscard(btndiscard) {
if (mydeleteok) {
return true
}
swal({
title: 'Are you sure?',
text: "You won't be able to revert this!",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
// for yes code, then do this:
myok = true
$(btndiscard).click()
所以,这就是它的工作原理:
你点击你的按钮。
Function 运行,返回false,服务端代码不运行。 现在显示对话框,整个 js function 完成,完成,退出 function。
现在,sweet alert 仍然显示该对话框。 如果你点击是,那么我们希望我们的服务器端按钮代码运行。
所以,我们设置我们的 myok 标志 = true,然后再次点击按钮!!!!
单击按钮,然后 myok = true,function 的第一部分现在可以返回 true,后面的服务器端代码现在将运行。
所以,设置看起来像这样:
<asp:Button ID="Button1" runat="server" Text="alert test"
OnClientClick="return mydelprompt(this)"
OnClick="Button1_Click" />
<script>
var myok = false
function mydelprompt(btn) {
if (myok) {
return true
}
swal({
title: "Are you sure?",
text: "Once deleted, you will not be able to recover this imaginary file!",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
myok = true
btn.click()
}
});
return false
}
</script>
所以,实际上我们最终点击了那个按钮两次!!!
第一次,用户点击。 上面的 function 运行,显示对话框,还返回 FALSE!!!! 不要忘记最后一行代码 - return false!!!!!
现在因为function返回false,那么我们的按钮点击(服务器端)代码没有运行,没有运行。
我们现在显示了甜蜜的对话框。 function 早已消失并运行并退出,,,。 -(记住,今天的 js 代码不会阻塞。不会停止——它不再真的被允许了,因为那会冻结浏览器。在短时间内我们甚至不允许使用 alert() 或 confirm()——它们会停止代码,它们将被折旧。
好的,所以显示对话框。 我们返回 false,按钮服务器端点击不运行。
你现在在甜蜜的警报中做出选择。 如果您确认“是”,则此代码运行:
.then((willDelete) => {
if (willDelete) {
myok = true
btn.click()
}
我们设置 myok = true,然后单击按钮。
怎么了?
我们的 function 再次运行,第一行代码是这样的:
if (myok) {
return true
}
因此,function 现在返回 true,现在我们的服务器端代码将运行。
所以,请记住,大多数(如果不是全部)js 代码运行并且是我们所说的异步(不停止 - 它运行到 function 的末尾,无需等待,无需停止。
因此,使用第二个代码示例来说明如何布局。
实际上,我们确实运行了该按钮代码两次。!! 用户第一次点击按钮 - 我们返回 false。
如果用户在 sweet alert 中回答 = yes,那么我们设置标志,然后再次单击 SAME 按钮,function 再次运行。 第一个 if (myok) 它命中,它返回 true,现在服务器端代码运行(因为我们对按钮单击返回 true)。
尝试第二个示例以及布局和方法。 这是 myok = true 的简单设置,然后在 js 中执行按钮单击,简单地“单击”该按钮,然后再次运行 js function。 我们真的不关心 function 再次运行,但我们最关心的是我们现在重击并将该例程设置为返回值 true,这意味着 function 返回 true,服务器端按钮事件现在运行,因此代码隐藏运行。
当然,如果用户不确认,那么我们就关闭对话框,什么也不会发生,我们也不在乎没有服务器端代码运行。
人们可能会使用 JavaScript 的按钮和“数据集”属性尝试上述操作。但是,您链接中的第一个建议有两个按钮,他们单击第二个按钮。 这不太理想,因为现在您必须向页面添加一个额外的按钮。 您还必须在标记中设置“数据集”属性,而您没有这样做。
所以,我认为简单的 myok 标志,不使用“数据集”,并且不必在页面上添加或使用隐藏的第二个按钮不太理想。 如果你说了几个按钮,情况尤其如此,你现在必须加倍这些按钮,加倍“div”和标记以添加数据集属性。
我只是认为飞机 jane myok 旗帜是一条坑坑洼洼少的道路。
但是,如果需要,您可以转储 myok 标志。 我只是测试这个,它工作正常:
function mydelprompt(btn) {
if (btn.dataset.myok) {
btn.dataset.myok = false
return true
}
swal({
title: "Are you sure?",
text: "Once deleted, you will not be able to recover this imaginary file!",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
btn.dataset.myok = true
btn.click()
}
});
return false
}
因此,如果您愿意,可以将“myok”变量添加到按钮 - 似乎有效,事实上我认为我更喜欢它。 那么,尽管我对在 DOM 和 JavaScript 中使用数据集表示“宽容”? 哎呀,我有点喜欢那个解决方案,这意味着我们不需要在脚本代码中创建一个额外的全局变量——这样更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.