Link to home
Start Free TrialLog in
Avatar of Dukster131
Dukster131Flag for United States of America

asked on

RadioButton not firing click event on first postback from inside nested Gridview

I have a nested gridview that I have a group of radio buttons on that are linked to answers for a question in the main gridview.  When I first click on the radio button, it does a post back, but the selection does not change.  If I click the button a second time it posts back and the click event fires.
 
How do I get the first click to fire the click event?
Avatar of guru_sami
guru_sami
Flag of United States of America image

- Make sure you are not rebinding in the PageLoad on postback
- Are you using UpdatePanel?
Can you share your some relevant code.
Avatar of Dukster131

ASKER

Thanks for your response.  

The nested gridview contains answers to a Question gridview.  So when I get the questions, it fires the Stored Procedure to get the answers for that question.  Since there is only one question per page, it has to fire on each new page.  However, that is not the problem.  As I said, I can retain the information, it is just a matter of making it select the chosen answer on the first click rather than having to click twice.   When reviewing the questions and answers, if the question was answered, it is checked.  However, to choose something else, it will post back and not change the selection or fire the click event for the radio button.  However, after that, it will function correctly for any radio button choice.  So the first time on the page it will post back when clicking the radio button, but will not change anything.  Subsequently, it will make the appropriate change and fire the click event.
Here is the source from the aspx page:

<asp:UpdatePanel ID="UPPNLTest" runat="server"><ContentTemplate>
<asp:Panel ID="pnlTest" runat="server">
    <table class="SMCTest">
         <tr>
        <td >
            <asp:Label ID="lblCount" runat="server" />
        </td>
    </tr>
    <tr>
        <td>
    <asp:GridView ID="gridQuestions" runat="server" AutoGenerateColumns="false"
                ShowHeader = "false" EnableViewState = "true"
                AllowPaging="True" onpageindexchanging="gridQuestions_PageIndexChanging" DataKeyNames="QID"
                PageSize="1" onrowdatabound="gridQuestions_RowDataBound" ShowFooter="True"
                FooterStyle-HorizontalAlign="Left"
                EmptyDataText="There is no test available at this time"
                onselectedindexchanged="gridQuestions_SelectedIndexChanged">
         <Columns>
                <asp:TemplateField HeaderText = "QID" SortExpression="QID" Visible = "false">
                    <ItemTemplate>
                        <asp:Label ID="lblQID" Text= '<%# Bind("QID") %>' runat="server"></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Question" SortExpression="QText">
               
                <ItemTemplate>
                    <table class="SMCTest">
                        <tr>
                            <td>
                      <asp:CheckBox ID="chkReview" runat="server" />&nbsp; &nbsp;<asp:Label ID="lblReview" runat="server" Text="Check here to come back to this question at the end of the exam."></asp:Label>
                            </td>
                        </tr>
                        <tr>
                            <td>
                    <asp:Label ID="lblQuestion" runat="server" Text=""></asp:Label>
                            </td>
                        </tr>
                        <tr>
                            <td>
                    <asp:Image ID="imgTest" runat="server" />
                   
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <asp:GridView ID="gridAnswers" runat="server" AutoGenerateColumns = "false" ShowHeader="false" OnRowDataBound="gridAnswers_RowDataBound" EnableViewState="true" DataKeyNames="AID">
                                    <Columns>
                                        <asp:TemplateField>
                                            <ItemTemplate>
                                                <asp:UpdatePanel ID="upRadioButton" runat="server"><ContentTemplate>
                                                <asp:RadioButton ID= "rdb"  runat="server" Text='<%# Bind("AText") %>'  OnCheckedChanged="rb_CheckedChanged" EnableViewState="true" ViewStateMode="Enabled"  AutoPostBack="True" Enabled="true" Visible="true"  />
                                               
                                                </ContentTemplate>
                                               
                                                </asp:UpdatePanel>
                                               
                                            </ItemTemplate>
                                        </asp:TemplateField>
                                    </Columns>
                                   
                                </asp:GridView>
                            </td>
                        </tr>
                    </table>
                </ItemTemplate>
                <FooterTemplate>
                   
                    <asp:Button ID="btnFinish" runat="server" Text = "Finish Exam" Visible = "true"
                        onclick="btnFinish_Click" />
                </FooterTemplate>
                <FooterStyle CssClass="RowAlignLeft"></FooterStyle>
            </asp:TemplateField>

           
        </Columns>

        <PagerSettings FirstPageText="" LastPageText="Finish Test"
                                    Mode="NextPrevious" NextPageText="Save and Continue" PreviousPageText="Previous Question" />
        <FooterStyle CssClass="RowAlignLeft" />
    </asp:GridView>
Nothing is clicking after looking at the code...but try this out...how about you remove the updatepanel from your second grid's radiobutton.

Also just wondering why you have RadioButton, did you consider using RadioButtonList instead?
I think this issue is due to Update panel.

First try it by removing all the update panels on your page.

otherwise ,There is a property "UpdateMode" for update panel. Set it to "Always".

I hope this will work.
update radio button on event by using trigger
I took out all the update panels but it still does not hold the check on the first click.  It does a postback but the OnCheckedChanged event does not fire.  The second time I click it, the OnCheckedChanged event does fire.
I am doing RowDataBound events for the Questions and answers.  The following code is what is being used.  Not sure if this is affecting the situation although everything populates correctly from the opening of the page.

 protected void gridQuestions_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            int intError;
            intError = 0;
            string strImage;
           
            int intQID = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "QID"));
            string strQuestion = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "QText"));
            if (DataBinder.Eval(e.Row.DataItem, "TestImage") != null)
            {
                strImage = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "TestImage"));
            }
            else
            {
                strImage = "";
            }
            var imgID = e.Row.FindControl("imgTest") as Image;
            var chkReview = e.Row.FindControl("chkReview") as CheckBox;
            var lblQuestion = e.Row.FindControl("lblQuestion") as Label;
            //chkReview.ID = intQID.ToString();

            lblQuestion.Text = strQuestion.Replace("\r\n", "<br /><br />");
            if (strImage != "")
            {
                imgID.ImageUrl = strImage;
                imgID.Visible = true;
            }
            else
            {
                imgID.Visible = false;
            }
           
            intQID = Convert.ToInt32(gridQuestions.DataKeys[e.Row.RowIndex].Value);
            GridView gridAnswers = e.Row.FindControl("gridAnswers") as GridView;

            try
            {
                using (SqlConnection conn = new SqlConnection(connectionString))
                {
                    conn.Open();

                    using (SqlDataAdapter comm = new SqlDataAdapter("dbo.GetSMCStudentTestAnswers", conn))
                    {
                        comm.SelectCommand.CommandType = CommandType.StoredProcedure;

                        comm.SelectCommand.Parameters.AddWithValue("@QID", intQID);

                        DataSet ds = new DataSet();

                        comm.Fill(ds);
                        DataTable dt = ds.Tables[0];

                        //gridAnswers.DataSource = dt.DefaultView;

                        gridAnswers.DataSource = ds;
                        //gridAnswers.EditIndex = -1;
                        gridAnswers.DataBind();
                    }
                }
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                intError = ex.Number;
                if (intError > 0)
                {

                }
            }
            //gridAnswers.EditIndex = -1;
        }
    }
    protected void gridAnswers_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //Get the number of documents per department
            int intAID = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "AID"));
            int intQID = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "QID"));
            var rdb = e.Row.FindControl("rdb") as RadioButton;
            var lblID = e.Row.FindControl("lblTaskID") as Label;
            //GridView gv = (GridView)gridQuestions.Rows[0].FindControl("gridAnswers");
           
            if (DataBinder.Eval(e.Row.DataItem, "AID") != DBNull.Value)
            {
                if (rdb != null)
                {
                rdb.ID = intAID.ToString();
                }
               
                //rdb.GroupName = "Answers";
                //this.Controls.Add(this.rdb);
                rdb.Enabled = true;
                //rdb.Focus();
                rdb.EnableViewState = true;
                //rdb.Visible = true;
                rdb.AutoPostBack = true;
                //rdb.GroupName = "Answers";
                gridQuestions.EditIndex =-1;
                //gv.EditIndex = -1;
            }
           
            }
        }
Anybody got any ideas?  I would really like to fix this.
My doubt is somewhere there is some rebinding is happening.
After your page first opens, place a break point on this line:  gridAnswers.DataBind();
Then check the radio button and see if you hit that line.

What does your event handlers look like e.g. Page_Load and onpageindexchanging?
I placed a break at the gridAnswers.DataBind() and when I clicked the radio button the first time, it did not stop at the break.

Here is my Page_Load

 if (!IsPostBack)
        {
            CheckStudentsAllowed();
            CheckTestActive();
            if ((User.IsInRole("SMCStudent") && intActiveTest == 1 && intAllowStudents ==1) || (!User.IsInRole("SMCStudent") && intActiveTest ==1))
            {
                NoCache();

                CheckAgreement();
                if (intAgree == 0)
                {
                    pnlAgreement.Visible = true;
                    GetAgreement();
                    pnlSummary.Visible = false;
                    btnReview.Visible = false;
                    btnContinue.Visible = true;
                    //pnlScores.Visible = false;
                    pnlTest.Visible = false;

                }
                else
                {
                    btnAgree.Visible = false;
                    btnReview.Visible = false;
                    btnContinue.Visible = false;
                }
                CheckPreviousTest();
                if (intTester == 1 || intTester==2)
                {
                    CheckEssayCount();
                    if (intEssay > 0)
                    {
                        Session["QTable"] = null;
                        Response.Redirect("TestGridViewEssay.aspx");
                    }
                    else
                    {
                        pnlAgreement.Visible = false;
                        pnlTest.Visible = false;
                        pnlSummary.Visible = false;
                        pnlFinish.Visible = true;
                        lblFinish.Text = "You have already taken this test and may not take it again.";
                        lblFinish.CssClass = "Warning";
                    }
                }
                if (intTester == 3 )
                {
                    getPreviousAnswers();
                }

                getQuestions();
                blModify = false;
                GetAnswerList();

                if (intTester == 3)
                {
                    PopulateCheckedValues();
                    PopulateReviewedValues();
                }
                btnReview.Visible = false;
                btnMissing.Visible = false;
                btnAll.Visible = false;
                //rdb.Attributes.Add("onclick", "javascript:return Validate()");
            }

            else
            {
                pnlAgreement.Visible = false;
                pnlTest.Visible = false;
                pnlSummary.Visible = false;
                pnlFinish.Visible = true;
                lblFinish.Visible = true;
                lblFinish.Text = "There are no active tests to take at this time.";
                lblFinish.CssClass = "Warning";
            }
        }
I am not sure what is wrong with the code and so I tried creating a sample page with a nested GV and radiobutton. I see the radiobutton firing upon first click.

Though I still don't understand, why do you use RadioButton instead of a RadioButtonList?

Edit: Ahhh...I see what's different that's causing the issue. It's setting the ID of the RadioButton in the gvAnswers_RowDataBound.
Comment out this line and your RB will start firing:
  rdb.ID = intAID.ToString();

Open in new window

You are correct, however if I do that, then I lose the ID for the radio button and I store the answer in an array that is tied to that ID.  So if they go back in the test, they no longer have the answers for those questions checked.

ArrayList arrChoices = (ArrayList)Session["CHECKED_ITEMS"];
        if (arrChoices != null && arrChoices.Count > 0)
        {
            GridView gv = (GridView)gridQuestions.Rows[0].FindControl("gridAnswers");
            foreach (GridViewRow gvrow in gv.Rows)
            {
                int index = (int)gv.DataKeys[gvrow.RowIndex].Value;
                if (arrChoices.Contains(index))
                {
                    RadioButton myCheckBox = (RadioButton)gvrow.FindControl("" + index);
                    myCheckBox.Checked = true;
                }
            }
        }
the myCheckBox.checked is now getting a null reference value.
But since each of your GridAnswers row will have one and only one radio, I am not sure why you need unique id.

From what I understand just this should work.
RadioButton myCheckBox = (RadioButton)gvrow.FindControl("rdb");


You haven't answered my question yet: Why are you using RadioButton over RadioButtonList. RBL would make all this very easy and you can get rid of your second grid gridAnswers.
 Check my sample page that uses RBL in one of it's column.
Well I thought about using a RadioButtonList but I thought a radio button that would grow based on the number of answers(which may change and is randomized) would work better.  I guess once I got the buttons working, I never went back to look at a radio button list.  I will check that out.
The reason I was keeping the ID was that if the session was lost, all the answers were stored in the database and I could regenate the AnswerID from that.  Without binding the ID on the answers rowdatabound, how do I bind the answerID to the radiobutton?  If I use ID = '<%# Bind("AID") %>'Instead of "rdb" I get the error The ID property of a control can only be set using the ID attribute in the tag and a simple value
ASKER CERTIFIED SOLUTION
Avatar of guru_sami
guru_sami
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your help.  I went with the Radiobuttonlist and you are correct, it worked like a charm.  I am tweaking it now to update the testing system, but while testing it on my development machine it works like a charm.  Thanks for your patience and assistance.