Home > OS >  c# asp.net Change GridView row color without postback
c# asp.net Change GridView row color without postback

Time:08-13

I have a gridview with a checkbox column. I need to change any row color to blue when checkbox is checked and back to white when unchecked. I had done it using c# but it needs postback to work and i cant have it. I tried using js but could send row info on click, on check box info. Is there anyway of changing it via client or changing via c# without postback?

my c# code

protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
    {
        foreach (GridViewRow row in GridView1.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                CheckBox chk = (CheckBox)row.FindControl("checkbox1");
                if (chk.Checked == true)
                {
                    row.BackColor = System.Drawing.Color.FromArgb(220,220,255);
                }
                else
                {
                    row.BackColor = System.Drawing.Color.White;
                }
            }
        }
    }

my asp.net code

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" ShowHeader="False">
                            <Columns>
                                <asp:TemplateField>
                                    <ItemTemplate >
                                        <div style="position:absolute;height:60px;width:60px;">
                                            <asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="false"  onclick="functionName(this);"  />
                                        </div>
                                        <asp:Button ID="Button100" runat="server" Height="60px" Width="60px" BackColor="Transparent"/>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:BoundField DataField="Id" ItemStyle-Width="5%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="PatientName" ItemStyle-Width="15%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="AccessionNumber" ItemStyle-Width="10%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="SeriesDescription" ItemStyle-Width="10%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="Status" ItemStyle-Width="8%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="CreationDateTime" ItemStyle-Width="10%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="PrintDateTime" ItemStyle-Width="10%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="CallingAetitle" ItemStyle-Width="12%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="CalledAetitle" ItemStyle-Width="12%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                                <asp:BoundField DataField="Pages" ItemStyle-Width="8%" ItemStyle-Height="60px" ItemStyle-Wrap="false" />
                            </Columns>
                            <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
                            <SelectedRowStyle BackColor="#999999" Font-Bold="True" ForeColor="Black"/>
                            <SortedAscendingCellStyle BackColor="#F1F1F1" />
                            <SortedAscendingHeaderStyle BackColor="#0000A9" />
                            <SortedDescendingCellStyle BackColor="#CAC9C9" />
                            <SortedDescendingHeaderStyle BackColor="#000065" />
                        </asp:GridView>
            
            
            <script type="text/javascript">
        function functionName(obj) {
            if (obj.checked) {
                alert('check box checked')
            } else {
                alert('check box not checked')
            }
        }
    </script>

CodePudding user response:

Yes, you can do it by using jQuery

First, change the <asp:TemplateField> section

<asp:TemplateField>
    <ItemTemplate>
        <div style="position: absolute; height: 60px; width: 60px;">
            <input type="checkbox" name="myCheckbox" id="myCheckbox" />
        </div>
        <asp:Button ID="Button100" runat="server" Height="60px" Width="60px" BackColor="Transparent" />
    </ItemTemplate>
</asp:TemplateField>

Add the following script

<script type="text/javascript">
    $(document).ready(function () {
        $(document).on("click", "#myCheckbox", function () {
            if ($(this).is(":checked")) {
                $(this).closest("tr").css("background-color", "blue");
            }
            else {
                $(this).closest("tr").css("background-color", "transparent");
            }
        });
    });
</script>

Explanation

  1. First we create an input tag of type checkbox
  2. Check for click event of that checkbox
  3. If checkbox is checked, then find the parent tr and set background-color to blue

CodePudding user response:

there are several ways to do this.

First up, as you dive into js code, TRY VERY hard, if not BEYOND super hard to avoid "onready" code, or js code that auto magic wires up a event for your button. (why? - becase then as a developer looking at the control and markup, I will have ZERO idea that some code some place else on the page is attaching a click event. This makes debugging and following code and markup BEYOND difficult to follow).

next up: Try to keep the existing type of control you had and WERE using. If you swap out and change the control type, then VERY HIGH chance that your existing code will break. Without a doubt, you check some rows on that GV, and THEN process the selected rows. So ZERO need to change, swap out, and introduce a new control into your GV - keep your existing asp.net check box control, so your code that process each row will continue to work.

Ok, so, you can consider the lazy bones way to do this, and just wrap the GV in a update panel. This will allow use of code behind, but you not suffer a full page post back.

Next up: Your first check box example process ALL grid rows - not required, and you can save some code. So, when you drop in a plane jane asp.net button, or say the check box with a post-back, then use this code to deal with the ONE row from the result of that button or control action. (you don't need to process all gv rows - just the one in question).

So

So this markup:

        <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False" 
            DataKeyNames="ID" CssClass="table" width="40%">
            <Columns>
                <asp:BoundField DataField="FirstName"   HeaderText="FirstName" />
                <asp:BoundField DataField="LastName"    HeaderText="LastName"  />
                <asp:BoundField DataField="City"        HeaderText="City" />
                <asp:BoundField DataField="HotelName"   HeaderText="HotelName"  />
                <asp:BoundField DataField="Description" HeaderText="Description"  />
                <asp:TemplateField HeaderText="Select " ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
                         OnCheckedChanged="chkSel_CheckedChanged"
                         AutoPostBack="true" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

Code to load, and our check box code:

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


    void LoadGrid()
    {
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            { 
                conn.Open();
                DataTable rstData = new DataTable();
                rstData.Load(cmdSQL.ExecuteReader());
                GVHotels.DataSource = rstData;
                GVHotels.DataBind();
            }
        }
    }

    protected void chkSel_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox ckBox = (CheckBox)sender;
        GridViewRow gRow = (GridViewRow)ckBox.NamingContainer;
        if (ckBox.Checked)
            gRow.Style.Add("background-color", "aliceblue");
        else
            gRow.Style.Add("background-color", "transparent");
    }

And we now get/have this with a few rows we checked

enter image description here

Note HOW the check box click event (with auto post-back) does not have to re-process the whole grid - so, much less code

Ok, so now lets do this without a post back. However, if that check box code (server side code) has other processing such as summing up price of products selected, then you MAY VERY well consider just keeping your code as is, and using a update-panel.

this will automatic ajax up the whole grid, and you not suffer a full page post-back.

So, drag drop in the scriptmanager (right after form tag).

Then in your page drop in a update paneal.

You wind up with this:

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
           "your grid view goes here"
        </ContentTemplate>
    </asp:UpdatePanel>

So, above means you don't have to change or re-wire up your existing code. You now not suffer a full page post-back. However, don't abuse the use of up-date panel. While they are absolute amazing, they still mean you do have a partial post back. But, really nice is no additional JavaScript or writing additional code (client side or even server side).

but, lets do this client side with javaScript.

So, our check box markup in the grid that was this:

<ItemTemplate>
    <asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
        OnCheckedChanged="chkSel_CheckedChanged"
        AutoPostBack="true" />
</ItemTemplate>

Now becomes this without post-back

        <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False" 
            DataKeyNames="ID" CssClass="table" width="40%">
            <Columns>
                <asp:BoundField DataField="FirstName"   HeaderText="FirstName" />
                <asp:BoundField DataField="LastName"    HeaderText="LastName"  />
                <asp:BoundField DataField="City"        HeaderText="City" />
                <asp:BoundField DataField="HotelName"   HeaderText="HotelName"  />
                <asp:BoundField DataField="Description" HeaderText="Description"  />
                <asp:TemplateField HeaderText="Select " ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
                        onclick="mycheckrow(this)" />
                </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

        <script>
            function mycheckrow(ckbox) {
                ck = $(ckbox)
                if (ck.is(":checked")) {
                    ck.closest("tr").css("background-color", "aliceblue");
                }
                else {
                    ck.closest("tr").css("background-color", "transparent");
                }
            }
        </script>

And now we get this:

enter image description here

I wanted a larger check box, so I added this before the grid

<style>
        .bigcheck input {width:20px;height:20px;vertical-align:middle;cursor:pointer}
 </style>

So in summary:

KEEP your existing check box - it has a "id" and is a standard asp.net check box - that way your eixsting code using and checking the check box server side will not break and does not have to be changed.

Never needed to process all rows in code behind. Note the use of "naming container". This works for a button also - so for gridview, repeater, listview etc., you can use this trick and NOT have to use rowcommand and the "messy" event model for a grid view.

So, our final markup looks like this:

    <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ID" CssClass="table" width="40%">
        <Columns>
            <asp:BoundField DataField="FirstName"   HeaderText="FirstName" />
            <asp:BoundField DataField="LastName"    HeaderText="LastName"  />
            <asp:BoundField DataField="City"        HeaderText="City" />
            <asp:BoundField DataField="HotelName"   HeaderText="HotelName"  />
            <asp:BoundField DataField="Description" HeaderText="Description"  />
            <asp:TemplateField HeaderText="Select " ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:CheckBox ID="chkSel" runat="server" CssClass="bigcheck"
                    onclick="mycheckrow(this)" />
            </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

    <script>
        function mycheckrow(ckbox) {
            ck = $(ckbox)
            mytr = ck.closest("tr")
            if (ck.is(":checked")) {
                mytr.css("background-color", "aliceblue");
            }
            else {
                mytr.css("background-color", "transparent");
            }
        }
    </script>

And we get this:

enter image description here

  • Related