sayguh
sayguh

Reputation: 2550

ASP.NET 2.0 with conditional radio button in a GridView

I'm looking to have a GridView displaying "Events" from a database, and then in the last column I want to do another database lookup (for each row) to see if that event is full or not.

If it's not full, display a radio button. If it is full display text "Full".

I think this is best done with OnRowDataBound event but could use a little help.

I can see how to change an asp label text but not display a radio button.

register.aspx:

<asp:GridView ID="GridView2" runat="server" DataSourceID="SqlDataSource2" AutoGenerateColumns=false CellPadding="5" HeaderStyle-BackColor="DarkGray" Width="450px" OnRowDataBound="GridView2_OnRowDataBound">
            <Columns>
                <asp:BoundField DataField="sessionDate" HeaderText="Date" DataFormatString="{0:D}" />
                <asp:BoundField DataField="sessionTime" HeaderText="Time" />
                <asp:BoundField DataField="site" HeaderText="Site" />
                <asp:BoundField DataField="room" HeaderText="Room" DataFormatString="{0:D}" />
                <asp:TemplateField HeaderText="">
                    <ItemTemplate>
                        <input type="radio" name="rdoSessionID" value='<%# Eval("ses_ID") %>' />



                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <HeaderStyle BackColor="#99CCFF" />
        </asp:GridView>
        <br />


        <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:sqlConnection2 %>"
            SelectCommand="SELECT * FROM dbo.sessions WHERE site LIKE @ses_site AND sessionDate = @ses_date ORDER BY sessionDate">

            <SelectParameters>
             <asp:SessionParameter name="ses_site" SessionField="ses_site" Type="String" />
             <asp:SessionParameter name="ses_date" SessionField="ses_date" Type="String" />
            </SelectParameters>



        </asp:SqlDataSource>

Upvotes: 1

Views: 1787

Answers (2)

Ryan Ternier
Ryan Ternier

Reputation: 8804

There are a few ways you can do this.

  1. You can do this on the OnRowDataBound , If the Item you're dealing with is a DataItem, grab the value you need from the current row, and do a quick DB Lookup
  2. When you get your resultset back from the database, do another lookup on each event. This way when your data leaves your data layer / methods you already have everything you need.
  3. Modify your SQL query to return this information with the list of events. You already know the Events, you could just have a sub query to query to see if it's full or not (or the # of people registered, and the Max # allowed so you can show that). This way you only have to do 1 hit against the database and it will save you a bunch of processing. (My favorite)

You would still need to overload the OnRowDataBound event for all 3 of those solutions. You'd hide the radio button if it was full, and ensure it was visible if the event was not full. The difference is where do you get your data.

Do you want to do:

1 Good hit (list of events) X amounts of small hits for each event

or

1 Good hit for list of events + if each event is full or not.

If you want to entertain #3, post your SQL Query and we can go from there.

Quick example of the OnRowDataBound event.

protected void MyGridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        CheckBox cbox = (CheckBox)e.Row.FindControl("chkBox");

        // Do some funky logic
        cbox.Visible = Event.HasRoom; //Boolean Propery
        // Or
        cbox.Visible = Convert.ToBoolean(DataBinder.Eval(e.Row.DataItem, "HasRoom").ToString());

    }
}

Update 1:

For your GridView, You can use

<ItemTemplate> 
   <asp:CheckBox runat="server" ID="Checkbox1" ToolTip=" Sign up For event " text="Event stuff" /> 
</ItemTemplate>

If you want to use a template, don't use a regular control, use a control.

For the query you could do the following. I'm not 100% sure on your table structure so I did it the way I normally would:

Table: Session (sess_id(PK), SessionDate, SessionTime, Site, Room) Table: Registrants (RegistrantID (PK), sess_id (FK to Session), UserID (FK to users that are registered)

SELECT SessionDate, SessionTime, Site, Room, ses_ID, 
(SELECT Count(ses_ID) FROM Registrants R WHERE R.Ses_ID= S.ses_Id) as [Registrants]
FROM dbo.Sessions s

Upvotes: 1

James Johnson
James Johnson

Reputation: 46047

Use the OnRowDataBound event, like this:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    RadioButton radio = e.Row.FindControl("RadioButton1") as RadioButton;
    if (radio != null)
    {
        radio.Visible = SomeCheckThatReturnsBoolean((int)GridView1.DataKeys[e.Row.RowIndex]["SomeID"]);
    }
}

If possible though, you should return the data with the GridView results, and store the value in a data key, so you can do something like this:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    RadioButton radio = e.Row.FindControl("RadioButton1") as RadioButton;
    if (radio != null)
    {
        radio.Visible = (bool)GridView1.DataKeys[e.Row.RowIndex]["SomeBooleanValue"];
    }
}

EDIT: Based on your comment to @Ryan, I think you should be able to include that flag in your query. I don't know your database at all, but you can try using a derived table or subquery to get the registrant session counts. Here's a rough example to work off of:

SELECT ID,
       ISNULL(Registrants.RegistrantCount, 0) RegistrantCount
       ...
FROM   Table1 t1
       LEFT OUTER JOIN (
           SELECT ForeignKeyID,
                  COUNT(RegistrantID) RegistrantCount
           FROM   Registrants
           GROUP BY ForeignKeyID
       ) Registrants
           ON Registrants.ForeignKeyID = t1.ID

Upvotes: 1

Related Questions