'asp.net gridview show hide controls on particular row

I have a gridview which is having one itemtemplate. Inside itemtemplate I have 4 controls 1.Dropdown1
2.Textbox1
3.Dropdown2
4.Textbox2.
Based on Dropdown1 value I should show/hide Dropdown2.
Based on Dropdown2 vlaue I should show/hide Textbox2.
I am able to achieve this thru code behind. But I want to implement this using javascript. Pls help. my gridview code is below:

<asp:GridView ID="gvVPEmailSent" runat="server" ShowHeader="true" EmptyDataText="There are no data records to display." PageSize="50"
    CssClass="table table-responsive border-info table-bordered table-hover table-small"
    AllowPaging="true" OnRowDataBound="gvVPEmailSent_RowDataBound" OnPageIndexChanging="gvVPEmailSent_PageIndexChanging"
    AllowSorting="false" OnRowCommand="gvVPEmailSent_RowCommand" AutoGenerateColumns="false" CellPadding="4">
    <Columns>
        <%--<asp:HyperLinkField HeaderText="RCM ID" ItemStyle-Width="10%" DataTextField="RCMID" />--%>
        <asp:TemplateField HeaderText="RCM ID" ItemStyle-Width="10%">
            <ItemTemplate>
                <asp:HyperLink ID="RequestId" runat="server" CausesValidation="false" Target="_blank"
                    NavigateUrl='<%# CreatePageUrl(Eval("RCMID"))%>' Text='<%#Eval("RCMID") %>' />
            </ItemTemplate>
        </asp:TemplateField>
        <%-- <asp:HyperLinkField HeaderText="View" ItemStyle-Width="5%" DataTextField="IssueUrl" />--%>
        <asp:BoundField HeaderText="Created on" ItemStyle-Width="10%" DataField="CreatedOn" DataFormatString="{0:MM-dd-yyyy}"/>
        <asp:BoundField HeaderText="Title" ItemStyle-Width="30%" DataField="Title" />
        <asp:BoundField HeaderText="Requestor" ItemStyle-Width="12%" DataField="Requestor" />
        <asp:BoundField HeaderText="Approved By" ItemStyle-Width="12%" DataField="ApprovedBy" />
        <%-- <asp:BoundField HeaderText="Reason for Approval" DataField="ReasonForApproval" />--%>
        <%--<asp:BoundField HeaderText="Comments" DataField="Comments" />--%>
        <asp:TemplateField HeaderText="Action">
            <ItemTemplate>
                <asp:Label CssClass="form-control" ID="lblReasonForApproval" Text='<%#Eval("ReasonForApproval") %>' runat="server" Visible="false" />
                <asp:DropDownList ClientIDMode="Static" CssClass="form-select" AutoPostBack="true" ID="cmbReasonForApproval" runat="server" onChange="ddlReasonForApprovalChange(this)" OnSelectedIndexChanged="cmbReasonForApproval_SelectedIndexChanged"></asp:DropDownList>
                <br />
                <asp:TextBox CssClass="form-control" runat="server" ID="Comments" Text='<%#Eval("Comments") %>' TextMode="MultiLine" Rows="2"></asp:TextBox>
                <br />
                 <asp:DropDownList CssClass="form-select" AutoPostBack="true" ID="cmbDeclineResolution" runat="server" OnSelectedIndexChanged="cmbDeclineResolution_SelectedIndexChanged"></asp:DropDownList>
               <br />
                <asp:TextBox CssClass="form-control" runat="server" ID="txtDecResValue" Text='<%#Eval("Comments") %>'  Visible="false"></asp:TextBox>
                

            </ItemTemplate>
        </asp:TemplateField>
        
    </Columns>
    <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" CssClass="table-info" />
    <PagerSettings Position="Bottom" />
    <RowStyle HorizontalAlign="Left" />
    <PagerStyle HorizontalAlign="Center" VerticalAlign="Middle" CssClass="pagination-ys" />
</asp:GridView>   

tried below javascript. but not working:

function ddlReasonForApprovalChange(el)
{ 
   var row = el.closest('tr'); // current row var valReason =el.options[el.selectedIndex].innerHTML; 
   var textbox = row.querySelector("#Comments"); // textbox in the same row var label = row.querySelector("#cmbDeclineResolution"); // label in the same row       
 // if current checkbox is checked show textbox and hide label
            if (valReason == 'Declined') {
              textbox.style.visibility = "visible";
              label.style.visibility = "hidden";
            // if current checkbox is unchecked hide textbox and show label
            } else {
              textbox.style.visibility = "hidden";
              label.style.visibility = "visible";
            }
    }


Solution 1:[1]

Ok, so you have this combo box - so you have to remove the autopostback=true, and of course remove the server side event.

We will replace that server side event with a client side event.

So, we will have this:

<asp:DropDownList CssClass="form-select"
    ID="cmbReasonForApproval" runat="server" 
   onChange="ddlReasonForApprovalChange(this)" >
</asp:DropDownList>

A few more things:

We do have to remove the ClientIDmode. Now, in 99% of cases, and when using js code, you OFTEN will of course use clientidmode="static", but this is one big exception, and the reason of course is that the control is in a gridview, and we need to let the grid view numbering system give each row and each control on that row its own id. If you set clientidmode="static", then this will get messed up.

Next up. As noted, there is no reason for the post back if we going to do this client side - so remove that.

and yes, we will pass "this" as the control.

Now the numbering mumbo jumbo? I don't bother to dechiper how it works, but ONLY know that the name of the control with all that extra mumbo jumbo attached to the name (control id) WILL be part of that "mess". But, we don't care, and we can use this fact to our advantage.

So, now, our client side event setting looks like this:

function ddlReasonForApprovalChange(el)
{
cboReason = $('#' + el.id)
myLabel = $('#' + el.id.replace("cmbReasonForApproval","lblReasonForApproval")
myTextBox = $('#' + el.id.replace("cmbReasonForApproval","Comments")

// now our logic
if (cboReason.val() == "Declined") {
   myTextBox.show()
   myLabel.hide()
}

So, what we do is get/grab the id, (that mumbo jump of the actual id name and a BUNCH of stuff that also generated for the row of the gv - but we don't care, nor even want to look at it. All we do this swap out the ddl "id" that contains that ddl id, and replace with the other control id's that we want. As noted, this is one of those exceptions in which we don't want to set clientidmode="static", since it winds up turning OFF the numbering system.

The above of course assumes you using jQuery

Also, you did you not set the DataTextField, and DataValue field in the markup. I do suggest you move the settings from behind to the markup.

That way, 5 different code stubs half way to Sunday can ALWAYS pull values, and you don't have to look, hunt down, or have multiple places in code that the two settings for the ddl/combo occurs in code behind.

The above is "air code", but you can see the idea/concept here. You pass "this", and from that we have the cbo, text box, and label.

As noted, do turn off clientidmode="static". If you don't do this, then you have to use the "name" of the control in jQuery, and not use "id", since it will be the same for each row when using static for controls in a gv.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Albert D. Kallal