javascript __doPostBack无法在函数后面调用gridView_RowCommand代码

piztneat  于 2023-06-04  发布在  Java
关注(0)|答案(1)|浏览(156)

我有下面的代码
Javscript

var tempRowId;
 function handleResetButton(rowId) {            
            tempRowId = rowId;
            openPopUp(); //which opens a customize pop up div box
 }

//when user triggers the Confirm Button in the customize pop up div box, will call doPostBack()
function doPostBack() {
     var gridView = document.getElementById('<%= gridView.ClientID %>');
     var row = gridView.rows[tempRowId];

     // Set the command arguments
     row.cells[0].innerHTML ="Reset";
     __doPostBack(gridView.id, 'RowCommand$' + tempRowId);                                         
 }

HTML

<asp:GridView ID="gridView" CssClass="table table-bordered table-hover" runat="server"
            CellSpacing="0" Style="max-width: 100%; font-size: 100%;"
            OnRowDataBound='gridView_RowDataBound' AutoGenerateColumns="false"
            OnRowCommand="gridView_RowCommand" ClientIDMode="Static" DataKeyNames="AccountId"
            UpdateMode="Conditional" ChildrenAsTriggers="false" ShowFooter="False">
            <AlternatingRowStyle BackColor="#ffffe0" />
<asp:TemplateField HeaderText="Action" HeaderStyle-Width="10%" ItemStyle-Width="10%" HeaderStyle-HorizontalAlign="Center" HeaderStyle-CssClass="center"
                    ItemStyle-HorizontalAlign="left" FooterStyle-Width="10%">
                    <ItemTemplate>
                        <asp:ImageButton ID="btnReset" Style="padding: 0px; margin: 0 10px 0 0; width: 24px; height: 24px; border: 1px solid #000000"
                            ImageUrl="../Script/Masters/images/refresh.png" ToolTip="Reset" CommandName="Reset" 
                           OnClientClick='<%# "handleResetButton("+ Container.DataItemIndex +");return false;" %>' runat="server" />
                    </ItemTemplate>
</asp:TemplateField>

C#代码背后

protected void gridView_RowCommand(Object sender, GridViewCommandEventArgs e)
    {
        var row = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
        var rowNo = row.RowIndex;
        var dataKey = gridView.DataKeys[rowNo];

        int accountId= Convert.ToInt32(dataKey.Value.ToString());

        switch (e.CommandName)
        {
            case "Reset":
                   //RUN CODE LOGIC
                break;

        }
    }

简单说明一下,当用户点击Reset按钮时,会弹出一个自定义的div框提示确认,当用户点击confirm按钮时,会运行doPostBack()javascript函数。我检查了它将运行doPostBack(),但它似乎没有在逻辑后面运行C#代码。是不是有什么我没有注意到或者处理不好的地方?

osh3o9ms

osh3o9ms1#

实际上,我从来没有真正为row命令费心。毕竟,将一个简单的按钮放入ListView,GridView,Repeater等?
你不需要使用row命令,它真的没有帮助。使用GridView行命令通常会迫使您在行命令事件中放入一堆“混乱”的case语句。(反正你也不需要用)。
此外,通过简单的按钮单击事件?与所有按钮一样,如果JavaScript返回true,则按钮代码(服务器端)将运行。如果客户端代码返回false,则代码不会运行。
因此,对于GridView行按钮单击,只需使用按钮的click事件。
所以,接下来我们处理如何返回true或false,即使在使用异步JavaScript代码时也要这样做。
首先,我们来看看如何使用按钮单击和事件来代替“蹩脚”的行命令。
所以,假设我们在一个网格中有这个简单的列表,我们有一个删除按钮,然后我们弹出一个jQuery.UI对话框来确认(删除或不删除)。
因此,我们有这样的标记:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ID"
    CssClass="table table-hover table-striped"
    Width="40%">
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
        <asp:BoundField DataField="LastName" HeaderText="LastName" />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
        <asp:BoundField DataField="City" HeaderText="City" />
        <asp:BoundField DataField="Description" HeaderText="Description" />

        <asp:TemplateField HeaderText="" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:ImageButton ID="cmdDelete" runat="server"
                    ImageUrl="~/Content/Reject80.png"
                    Width="32"
                    OnClick="cmdDelete_Click"
                    />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

将按钮(或图像按钮)放在GridView内部意味着我们不能双击按钮(以创建单击事件)。但是,如果在标记中键入OnClick=,则会注意到intel-sense会弹出一个上下文对话框,为后面的代码创建事件。
所以,我们现在有了Gridview的代码:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {

        GridView1.DataSource = General.MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
        GridView1.DataBind();

    }

    protected void cmdDelete_Click(object sender, ImageClickEventArgs e)
    {

        ImageButton cmdDel = (ImageButton)sender;
        GridViewRow gRow = (GridViewRow)cmdDel.NamingContainer;

        int RowIndex = gRow.RowIndex;
        int PKID = (int)GridView1.DataKeys[RowIndex]["ID"];

        // delete this row
        SqlCommand cmdSQL = 
            new SqlCommand(("DELETE FROM tblHotelsA WHERE ID = @ID"));
        cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PKID;
        General.MyRstE(cmdSQL);

        LoadGrid();

    }

现在,注意sender的使用(获取按钮),然后注意命名容器的使用。这适用于列表视图,网格视图,中继器等。
因此,请注意我们如何不必传递行索引,注意我们如何获得完整的GridView行,并注意我们如何获得dataKeys PK数据库值。
所以,上面是相当不错的,因为如果我们添加几个按钮,GridView/ListView等?
我们不会乱用row命令。
当然,上面的单击将运行按钮代码,并删除我们的行。
现在,让我们添加一个客户端对话框。这个对话框可以做很多我们想做的事情,但是当我们确认这个对话框时,我们希望后面的代码(图像按钮单击事件代码后面运行)。
因此,让我们添加客户端代码和jQuery.UI确认对话框。
当然,像“大多数”对话框和例子,如甜蜜警报等?
他们不会等待或停止代码。所以,我们必须
让客户端代码运行,返回false,显示对话框。
如果用户点击取消,则关闭对话框-不执行任何操作。
如果用户接受(确认),那么我们设置标志= true,然后再次单击SAME按钮,这一次,由于例程返回true,因此服务器端(后面的代码运行)。
我们不能使用JavaScript promise和“await”,但是添加上面的标志也可以。
所以,让我们将客户端代码+ click添加到按钮click,现在我们有了这个:

<asp:TemplateField HeaderText="" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:ImageButton ID="cmdDelete" runat="server"
                    ImageUrl="~/Content/Reject80.png"
                    Width="32"
                    OnClick="cmdDelete_Click"
                    OnClientClick="return myconfirm(this)"
                    />
            </ItemTemplate>
        </asp:TemplateField>

客户端代码现在是这样的:

<div id="myconfirmdiv" style="display:none">
            <h3><i>Delete this hotel?</i></h3>
            <i>(This can't be undone)</i>
        </div>

        <script>

            var myok = false
            function myconfirm(btn) {
                if (myok) {
                    return true
                }
                myDialog = $("#myconfirmdiv")

                myDialog.dialog({
                    title: "Delete?",
                    modal: true,
                    sizable: true,
                    width: '380',
                    closeText: "",
                    position: { my: 'left top', at: 'right bottom', of: btn },
                    buttons: {
                        Ok: function () {
                            myok = true
                            btn.click()
                        },
                        Cancel: function () {
                            myDialog.dialog('close')
                        }
                    }
                })
                return false
            }

        </script>

结果是这样的:

因此,上面:
我们不必关心混乱的行命令--你很少需要它们,而且它们对你没有多大帮助。
你可以传递这个按钮,然后点击它,如上所示,使用“NamingContainter”获取网格行,从那里你可以获取行索引,然后获取datakey,当然你可以对该行使用find control(对于模板化的列),或者使用.cells[]从GridView获取非模板化的单元格。
所以上面去掉了row命令。
避免使用__DoPostBack。
避免了在JavaScript中传递“index”值。
摆脱了必须尝试并向服务器传递一些行索引(代码隐藏)。
它摆脱了…好吧,我可以继续写,但你在这里得到的想法。
在上面,我使用了jQuery,还有jQuery.UI,它有上面的“dialog”控件。如前所述,这些对话框不会停止代码,因此在第一次单击按钮时,代码显示对话框,运行并返回false(因此服务器端代码不会运行)。如果我们点击“ok”确认,那么flag设置为true,我们再次单击SAME按钮,这一次,它返回true,因此后面的服务器端代码运行。

相关问题