繁体   English   中英

使用 asp.net 按钮的 SweetAlert 确认不流向服务器端程序的问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM