Search code examples
c#asp.netgridviewselectcommand

GridView - Client Side "WHERE" clause in the SqlDataSource?


I have a GridView with a TemplateField containing a button. This button opens up a modal window which contains another GridView as seen below:

Template Field in Gridview1:

<asp:TemplateField>
<ItemTemplate>
    <asp:Button ID="btnOpen" runat="server" Text="Show Gridview" OnClick="btnOpen_Click" data-toggle="modal" data-target="#myModal"/>
</ItemTemplate>

Modal Window:

<div class="modal" id="idModal">
        <div class="container">
            <div class="modal-header">
                <h1>Transaction Details<a class="close-modal" href="#">&times;</a></h1>
            </div>
            <div class="modal-body">
                <asp:GridView ID="gvDetail" runat="server" AutoGenerateColumns="false" DataSourceID="SqlgvDetail"
                OnRowDataBound="gvDetail_RowDataBound" CssClass="table table-hover table-bordered" EmptyDataText="No data to display.">
                    <Columns>
                        <asp:BoundField DataField="metalid" HeaderText="Metal ID"/>
                        <asp:BoundField DataField="enddate" HeaderText="End Date" DataFormatString="{0:dd-MM-yyyy}" />
                        <asp:BoundField DataField="startdate" HeaderText="Start Date" DataFormatString="{0:dd-MM-yyyy}" />
                        <asp:BoundField DataField="clientref" HeaderText="Client Ref" />
                        <asp:BoundField DataField="quantity" HeaderText="Quantity" DataFormatString="{0:N2}" />
                    </Columns>
                </asp:GridView>
            </div>
            <div class="modal-footer">
                <asp:Button ID="btn_close" runat="server" Text="OK" CssClass="close-modal btn-sm btn-primary"/>
            </div>
        </div>
    </div>
    <div class="modal-backdrop"></div>

GridView2 SqlDataSource:

<asp:SqlDataSource ID="SqlgvDetail" runat="server" ConnectionString="<%$ ConnectionStrings:InventoryConnectionString %>"
    SelectCommand="SELECT td.metalid , td.enddate , td.startdate , td.clientref , td.quantity FROM trxdetail td">
</asp:SqlDataSource>

Now this code works fine and opens up the modal window with the SelectCommand as expected. However, I need to add a where clause based on a row value from GridView1. E.g. ...WHERE td.clientref = GridView1.SelectedRow.Cells[0].Text

Help please!

Edit: Modal Window:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title" id="myModalLabel">Modal title</h4>
                </div>
                <div class="modal-body">
                    <asp:GridView ID="gvDetail" runat="server" AutoGenerateColumns="false" DataSourceID="SqlgvDetail"
                    OnRowDataBound="gvDetail_RowDataBound" CssClass="table table-hover table-bordered" EmptyDataText="No data to display.">
                        <Columns>
                            <asp:BoundField DataField="metalid" HeaderText="Metal ID"/>
                            <asp:BoundField DataField="enddate" HeaderText="End Date" DataFormatString="{0:dd-MM-yyyy}" />
                            <asp:BoundField DataField="startdate" HeaderText="Start Date" DataFormatString="{0:dd-MM-yyyy}" />
                            <asp:BoundField DataField="clientref" HeaderText="Client Ref" />
                            <asp:BoundField DataField="quantity" HeaderText="Quantity" DataFormatString="{0:N2}" />
                        </Columns>
                    </asp:GridView>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-primary">Save changes</button>
                </div>
            </div>
        </div>
    </div>

Modal JS:

$(document).ready(function () {
        $("#btnOpen").click(function () {
            $("#myModal").modal();
        });
    });

Solution

  • You can actually set an <asp:ControlParameter> to the SelectedValue of a GridView. I think this is what you are looking for. As the documentation says:

    As a further shortcut, you can directly determine the data key value of the first key field of the selected row by using the SelectedValue property.

    So what you can do is set the DataKeyNames value on GridView1 to whatever value it is that you want to use in the WHERE clause.

    <asp:GridView ID="GridView1" runat="server" DataKeyNames="clientref"
        ...
    </asp:GridView>
    

    Then set that as the control parameter in your SqlDataSource.

    <asp:SqlDataSource ID="SqlgvDetail" runat="server"
        ConnectionString="<%$ ConnectionStrings:InventoryConnectionString %>"
        SelectCommand="SELECT td.metalid, td.enddate, td.startdate, td.clientref , td.quantity 
                       FROM trxdetail td
                       WHERE clientref=@clientref">
        <SelectParameters>
            <asp:ControlParameter ControlID="GridView1"
                PropertyName="SelectedValue"
                Name="clientref"
                Type="Whatever type clientref is" />
        </SelectParameters>
    </asp:SqlDataSource>
    

    Just remember you need to make sure the row in GridView1 is actually marked as the SelectedRow. You can do this in your button click event.

    protected void btnOpen_Click(object sender, EventArgs e)
    {
        // Find the index to select
        Button btnOpen = (Button)sender;
        GridViewRow row = (GridViewRow)btnOpen.NamingContainer;
        int selectedIndex = row.DataItemIndex;
    
        // Set the selected index of the GridView
        GridView1.SelectedIndex = selectedIndex;
    
        // Bind the detail GridView now that the row is selected so 
        // that its SqlDataSource can get a SelectedValue for the
        // parent GridView
        gvDetail.DataBind();
    }