Updatepanel UI not updating when button clicked from Gridview

227 Views Asked by At

My updatepanel's UI is not updating when a linkbutton is clicked from within the gridview. The Updatepanel that I want to update is not inside the gridview. So this is my code:

  <asp:ScriptManager EnablePartialRendering="true"
ID="ScriptManager1" runat="server">
 </asp:ScriptManager>

//<asp:GridView ID="attendanceGv" runat="server" CssClass="table table-striped table-bordered" AutoGenerateColumns="False" ShowHeader="False" OnRowDataBound="GridViewRowEventHandler" > //  I tried this with regular onlick but it did not work.
<asp:GridView ID="attendanceGv" runat="server" CssClass="table table-striped table-bordered" AutoGenerateColumns="False" ShowHeader="False" OnRowDataBound="GridViewRowEventHandler" OnRowCommand="GridView1_RowCommand"> 
  <Columns>
 <asp:BoundField DataField="Field1" SortExpression="Field1" ItemStyle-Width="8%" />
 <asp:TemplateField>
  <ItemTemplate>
  //  <asp:LinkButton ID="expandLBtn" runat="server" OnClick="expandLBtn_Click"><i class="fa-solid fa-arrow-right">
  </i></asp:LinkButton> // I tried this with the onclick command and trigger. (Also without the trigger)
<asp:LinkButton ID="expandLBtn" runat="server" CommandName="UpdateTextBox"
 CommandArgument='<%# Eval("nyeis_id") %>' ><i class="fa-solid fa-arrow-right">
  </i></asp:LinkButton>
  </ItemTemplate>
 </asp:TemplateField>
  </Columns>
</asp:GridView>


 <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
 <div class="row ">
  <div class=" col-12">
<asp:Label ID="Label2" CssClass="form-control" runat="server" Text="test1" Style="text-align: center;" Font-Bold="True" ></asp:Label> 
  </div>
 </div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="attendanceGv" EventName="RowCommand" /> // without this trigger, i kept getting regular post back. With this trigger I get Async but the UI does not update. 
 //<%--  <asp:AsyncPostBackTrigger ControlID="expandLBtn" EventName="Click" />--%> // tried this with the regular click event. 
</Triggers>
</asp:UpdatePanel>

C# : this is what I did when I was using the onclick

 protected void expandLBtn_Click(object sender, EventArgs e)
        {


            GridViewRow row = (GridViewRow)((LinkButton)sender).NamingContainer;


           
            HtmlControl FlagAttendanceDetailsCol = (HtmlControl)attendanceDetailsCol.FindControl("attendanceDetailsCol");
            UpdatePanel FlagUpdatePanel2 = (UpdatePanel)FlagAttendanceDetailsCol.FindControl("UpdatePanel2");
            System.Web.UI.WebControls.Label FlagLabel2 = (System.Web.UI.WebControls.Label)FlagUpdatePanel2.FindControl("Label3");
            FlagLabel2.Text="test";

            Label2.Text = "New value2";
            UpdatePanel2.Update();
        }

C#: This is what I tried when using GridViewCommandEventArgs

if (e.CommandName == "UpdateTextBox")
        {

            int rowIndex = Convert.ToInt32(e.CommandArgument);

            LinkButton FlagExpandLBtn = attendanceGv.Rows[rowIndex].FindControl("expandLBtn") as System.Web.UI.WebControls.LinkButton;
            ScriptManager1.RegisterAsyncPostBackControl(FlagExpandLBtn);


            // Here, you can retrieve the data associated with the row that contains the clicked button and
            // perform any necessary data operations.
            System.Web.UI.WebControls.Label txtBox2 = UpdatePanel2.FindControl("Label2") as System.Web.UI.WebControls.Label;
            System.Web.UI.WebControls.Label txtBox3 = UpdatePanel2.FindControl("Label3") as System.Web.UI.WebControls.Label;
            if (txtBox2 != null)
            {
                txtBox2.Text = "test2";
                // call the Update method on the UpdatePanel
            //    Label2.Text = "New value"; // Update the TextBox in the other UpdatePanel.
                attendanceDetailsCol.Visible = true;
               
            }
            if (txtBox3 != null)
            {
                txtBox3.Text = "test3";
                // call the Update method on the UpdatePanel
            //    Label3.Text = "New value"; // Update the TextBox in the other UpdatePanel.
                attendanceDetailsCol.Visible = true;

            }

            string test = Label2.Text;
            string test2 = Label3.Text;

            UpdatePanel2.Update();


        }

I tried debugging and I do not get any errors and before I get to the updatepanel2.update section, the textboxes shows that it was changed, but it never shows in the UI.

1

There are 1 best solutions below

1
Albert D. Kallal On

Edit: this can work!

Ok, the issue of course is that the button and gv is OUTSIDE of the up.

As a "normal" rule, you can have ANY button on the page trigger the update panel.

However, inside of a gridview? No, since the update panel needs this:

<asp:GridView ID="GridView1" runat="server"
    AutoGenerateColumns="False" DataKeyNames="ID"
    CssClass="table" Width="60%" ShowHeaderWhenEmpty="true">
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName" HtmlEncode="false" />
        <asp:BoundField DataField="LastName" HeaderText="LastName" HtmlEncode="false" />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
        <asp:BoundField DataField="City" HeaderText="City" />
        <asp:BoundField DataField="Province" HeaderText="Province" />
        <asp:BoundField DataField="Description" HeaderText="Description" />
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button ID="Button1" runat="server" Text="This row"
                    OnClick="Button1_Click" />
            </ItemTemplate>
        </asp:TemplateField>

    </Columns>
</asp:GridView>



<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <h3>Inside up <%= DateTime.Now.ToString() %></h3>

        Row click =
        <asp:TextBox ID="txtRowClick" runat="server"></asp:TextBox>


    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="Button1" EventName="onclick" />
    </Triggers>
</asp:UpdatePanel>

Note the setting for ControlID. Well, that would work if the trigger button was NOT inside of a gv.

There are several ways, but if your GV only has that button, or a few others?

Then you can define the WHOLE GridView as a trigger.

So, then THIS will work:

            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Gridview1" />
            </Triggers>

So, you say the trigger is the whole GV, and you don't specify the event.

So, next issue, it was not made clear by the poster if the link button click was working or not?

What follows are solutions for this:

Another possible road

Place the GV in a update panel also.

And when you do this, then all panels on that page will be posted to the server. So, in theory, all you require is a working button in the GV. If you place the GV in the same update panel, or even a separate one, then again this will work, since by default ALL update panels are posted back to the server. The result then is code behind can work with, modify any controls in ANY of those up's.

However, the following narrative below can still be of help, since I have often seen link buttons NOT work, and the following explains workarounds for this issue:

First up, try dumping the use of command name.

Just add a onclick event to the expandLBtn button (it is a link button, but you can still have a onclick event).

So, the button (link button) will look like this:

            <ItemTemplate>
                <asp:LinkButton ID="expandLBtn" runat="server"                         
                    CommandArgument='<%# Eval("nyeis_id") %>'
                    OnClick="expandLBtn_Click"
                    >
                    <i class="fa-solid fa-arrow-right"></i></asp:LinkButton>

            </ItemTemplate>

HOWEVER and a big one:

I have found for some reason that if you add a "span" or a "i" for the bootstrap icon (or in your case Font Awesome), the click event starts to not work when the whole GridView (or ListView) is placed inside of a update panel.

I have NOT been able to determine why this is so. (but, the existence of the span with the icon is what cases this to fail.

So, to verify the above? Try using a plain button (again without the commandName, but you are free to use the command argument).

In fact, try this first without the commandName - and a specified click event for the Linkbutton.

As noted, even your existing Linkbutton? Remove the span or "i", remove the commandName, keep the command argument, and use that click event + naming container as you are to pick up the current row click.

I tend to only see this bug/issue when you nested more then one gv, and then place the whole deal inside of a update panel.

So, if you find that the linkbutton works (without the icon), then:

You have to adopt a button - I just don't have a better answer.

You can also use a image button (and presumably a icon for that).

And you can ALSO say for the 1 or 2 icons you have?

Go to:

https://fontawesome.com/search?s=solid&f=sharp&o=r

Now, select the icon, and you have a chance to download the icon as a "image" (SVG) file.

You can then style a regular button like this:

<style type="text/css">
    .bEdit {
        border: 1px solid #563d7c;
        border-radius: 5px;
        color: white;
        padding: 5px 10px 5px 25px;
        background: url(Content/Icons/pencil-square.svg) left 3px top 5px no-repeat skyblue;
    }
</style>

And then your button becomes this:

                <asp:Button ID="cmdEdit3" runat="server" Text="Edit" CssClass="btn bEdit" 
                    OnClick="cmdEdit3_Click"
                    />

Use above if you want icon + text in button.

If you ONLY want/need the icon in the button?

then of course use a image button based on that SVG.

Say this:

   <asp:ImageButton ID="cmdDelete" runat="server" 
                CssClass="btn btn-default"
                ImageUrl="~/Content/Icons/trash.svg"
                />

So, above better choice depends if you need icon only, or icon + text. If you ONLY need icon? then use a image button + the SVG icon.

The suggested solution here:

ONLY required if you have a nested GridView (or ListView).

ONLY required if the whole mess is in a update panel.

If you are not nesting that GridView inside another, then everything works, and in fact works without a update panel.

From what I can experience?

The "span" or the "i" to insert the icon is what causes the failure. You can as a test keep your existing code, and remove the icon, and see if button works for you. (it likely will).

So, either:

Adopt a plain button + style sheet to display the SVG icon. (do this if you need/want icon + text)

Adopt a image button, specify the image - again this will work. (this suggest is when you only want icon).

However, since your current example does NOT have a nested GridView inside of a GridView?

Then using a plain click event for that link button should work. (remove the commandname).