Issue with Ajax using RadioButtonList

2 posts, 0 answers
  1. Derrick
    Derrick avatar
    2 posts
    Member since:
    Sep 2010

    Posted 14 Nov 2011 Link to this post

    Hey guys,

    I'm redoing some code that was written by a previous coder. Basically, we have a poll, where we see the question (an optional question image) and 2-10 answers (with their optional images). There's also a ticker that ticks every 5 seconds. There's tons of ajax programmed in which causes the RadioButtonList and the button label (lblMessage) to refresh every 5 seconds. The images and the answer text are loaded into the list items of the RadioButtonList. So every 5 seconds or anytime a different radio button is selected, the images are repainted. Which makes the website really hard to look at more than a minute or two.


    We do need the ajax for the radiobuttonlist due to the timer, unless there's another way to go around this. If the poll ends and the user selects a different answer, it will disable the radio buttons and notify that the poll is over. So I'm wondering if there's anyway to separate the images from the RadioButtonList, or another way to keep the images from repainting without losing functionality.

    <%@ Page Title="ViaConnect-Quick Poll" Language="C#" MasterPageFile="~/Student/StudentInterfaceMaster.Master"
        AutoEventWireup="true" CodeBehind="QuickPoll.aspx.cs" Inherits="ViaStudent.Student.QuickPoll" %>
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Charting" TagPrefix="telerik1" %>
    <%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
      
    <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
            <script type="text/javascript">
                $(document).ready(function () {
      
                    $('#nav-primary-quick').addClass('selected');
                });
            </script>
            <script type="text/javascript" language="javascript">
                var fooElement = document.getElementById("questionText");
            </script>
    </asp:Content>
      
    <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
        <style type="text/css">
            .answer_container1
            {
                padding:0;
                margin:10px;
                font-size:12px;
                width:100%;
            }
            .lblClass
            {
                width:662px;
            }
        </style>
        <telerik:RadWindowManager ID="RadWindowManager1" runat="server" />
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="TimerActiveTime">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="lblTimerActiveTime" />
                        <telerik:AjaxUpdatedControl ControlID="rdoQuickAnswer" />
                        <telerik:AjaxUpdatedControl ControlID="imgBtnRefresh" />
                        <telerik:AjaxUpdatedControl ControlID="lblMessage" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="rdoQuickAnswer">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="panelQuickPoll" />
                        <telerik:AjaxUpdatedControl ControlID="lblCheckAnswer" />
                        <telerik:AjaxUpdatedControl ControlID="rdoQuickAnswer" />
                        <telerik:AjaxUpdatedControl ControlID="lblMessage" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
            <AjaxSettings>
                <telerik:AjaxSetting AjaxControlID="imgBtnRefresh">
                    <UpdatedControls>
                        <telerik:AjaxUpdatedControl ControlID="panelQuickPoll" />
                        <telerik:AjaxUpdatedControl ControlID="rdoQuickAnswer" />
                        <telerik:AjaxUpdatedControl ControlID="imgBtnRefresh" />
                        <telerik:AjaxUpdatedControl ControlID="lblMessage" />
                    </UpdatedControls>
                </telerik:AjaxSetting>
            </AjaxSettings>
        </telerik:RadAjaxManager>
      
        <div class="body_left_container">
            <div class="body_title_bg_box">
                <div class="body_title_left_bg"></div>
                <div class="body_title_middle_bg font_16_blue">
                    <div class="quickpoll_left_title">Quick Poll:  </div>
                    <div class="left">
                        <asp:Timer ID="TimerActiveTime" runat="server" OnTick="TimerActiveTime_Tick" Interval="5000" />
                        <asp:Label ID="lblTimerActiveTime" runat="server" />
                    </div>
                </div>
                <div class="body_title_right_bg"></div>
            </div>
            <div class="question_container_1 font_18">
                <asp:Label ID="lblTypeOfAssesment" runat="server" /></div>
            <div class="quiz_body_inner_box_2">
                <asp:Panel ID="panelQuestionText" CssClass="question_container" runat="server">
                    <asp:Label ID="lblQuestionText" runat="server" />
                    <div class="question_icon_1">
                        <telerik:RadToolTip ID="questionToolTip" runat="server" Animation="Fade" EnableShadow="False"
                            Position="TopCenter" RenderInPageRoot="true">
                            <asp:Image ID="imgQuestionToolTip" runat="server" />
                        </telerik:RadToolTip>
                        <asp:Image ID="imgQuestion" runat="server" />
                    </div>
                </asp:Panel>
      
                <asp:Panel ID="panelAnswer" CssClass="answer_container1" runat="server">
                    <asp:RadioButtonList ID="rdoQuickAnswer" CssClass="lblClass" runat="server" CellPadding="0" CellSpacing="10"
                        RepeatLayout="Table" OnSelectedIndexChanged="rdoQuickAnswer_SelectedIndexChanged"
                        AutoPostBack="true" />
                    <div class="quiz_body_inner_box_2 font_16_grey">
                        <asp:Label ID="lblMessage" CssClass="error_message" runat="server"></asp:Label>
                    </div>
                </asp:Panel>
                <div id="resultLabel" runat="server" class="font_14 bold" visible="false"></div>
            </div>
            <div class="quiz_test_box"></div>
        </div>
    </asp:Content>


    and here is the code behind

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Xml;
    using Telerik.Charting;
    using Telerik.Charting.Design;
    using Telerik.Charting.Styles;
    using Telerik.Web.UI;
    using ViaData;
    using ViaData.Entities;
    using ViaLibrary;
      
    namespace ViaStudent.Student
    {
        public partial class QuickPoll : Navigation
        {
            private ViaEntities contextVia = new ViaEntities();
      
            private int studentClassId;
            private int assessmentId;
            private DateTime startTimeUTC;
            private int isCompletedCode;
            private int assessmentQuestionId;
            private int questionId;
            private string questionText;
            private bool questionHasMedia;
            private string pollElapsedTime;         // Time elapsed since Quick Poll was published
            private bool validPollExists = true;    // Is there a Quick Poll associated with this student/class
            private bool isPollActive;              // If a Quick Poll exists, is it an active poll
            int rdoQuickAnswerIndex;                // rdoQuickAnswer selected index
              
            protected void Page_Load(object sender, EventArgs e)
            {
                SetQuickPollDetails();  // Set ViewState variables
                if (!Page.IsPostBack)
                {
                      
      
                    if (validPollExists)                  
                    {
                        SetCompletedStatus();       // Set isPollActive global variable
                        BindQuestionText();         // Sets question text label and image
                        BindRdoQuickAnswer();       // Sets RadioList options and images
                        SetMessages();              // Sets lblMessage text with student response info
                    }
                    else
                    {
                        TimerActiveTime.Enabled = false;
                        imgQuestion.Visible = false;
                        lblTimerActiveTime.Text = "No Quick Polls exist for this class";
                    }
                }
                else // Set global variables from ViewState
                {
                    if (validPollExists)
                    {
                        studentClassId = Convert.ToInt32(ViewState["StudentClassId"]);
                        assessmentId = Convert.ToInt32(ViewState["AssessmentId"]);
                        startTimeUTC = Convert.ToDateTime(ViewState["StartTimeUTC"]);
                        assessmentQuestionId = Convert.ToInt32(ViewState["AssessmentQuestionId"]);
                        questionId = Convert.ToInt32(ViewState["QuestionId"]);
                        questionText = ViewState["QuestionText"].ToString();
                        questionHasMedia = Convert.ToBoolean(ViewState["QuestionHasMedia"].ToString());
                    }
                }
      
                if (validPollExists)
                {
                    ViewState["RdoQuickAnswerIndex"] = rdoQuickAnswer.SelectedIndex;
                    rdoQuickAnswerIndex = rdoQuickAnswer.SelectedIndex;
      
                    TimeSpan timeElapsed = DateTime.UtcNow - startTimeUTC; // Time elapsed since poll was started
                    pollElapsedTime = timeElapsed.ToString("hh':'mm':'ss"); // String format of timeElapsed
      
                    SetCompletedStatus();
                    if (isPollActive)
                        lblTimerActiveTime.Text = pollElapsedTime;
                    else
                        lblTimerActiveTime.Text = "Completed";
                }
            }
      
            #region Private Methods
      
            // Set global variables
            private void SetQuickPollDetails()
            {
                student_class studentClass = (student_class)Session["studentClass"]; // studentClass.student_class_id;
                studentClassId = studentClass.student_class_id; // StudentBase Session["studentClass"]
      
                // Returns IList of Quick Polls: active first, then past poll, else empty list
                var aqId = (from aq in contextVia.GetQuickPollByStudentClassId(studentClassId)
                            select aq).ToList();
      
                if (aqId.Count > 0) // If at least one active or completed quick poll exists
                {
                    validPollExists = true;
      
                    // If poll is active
                    if (aqId[0].is_completed == (int)Enums.CompletedCode.Published)
                        isPollActive = true;
                    else
                        lblTimerActiveTime.Text = "Completed";
      
                    // Set global variables from db or controls
                    assessmentId = aqId[0].assesment_id;
                    assessmentQuestionId = aqId[0].assesment_question_id;
                    isCompletedCode = Convert.ToInt32(aqId[0].is_completed);
                    startTimeUTC = Convert.ToDateTime(aqId[0].start_time);
                    questionId = Convert.ToInt32(aqId[0].question_id);
                    questionText = aqId[0].question_text.ToString();
                    questionHasMedia = Convert.ToBoolean(aqId[0].has_media);
      
                    // Set ViewState­­® variables from global variables
                    ViewState["StudentClassId"] = studentClassId;
                    ViewState["AssessmentId"] = assessmentId;
                    ViewState["AssessmentQuestionId"] = assessmentQuestionId;
                    ViewState["StartTimeUTC"] = startTimeUTC;
                    ViewState["IsCompletedCode"] = isCompletedCode;
                    ViewState["QuestionId"] = questionId;
                    ViewState["QuestionText"] = questionText;
                    ViewState["QuestionHasMedia"] = questionHasMedia;
                }
                else // If no active or completed polls exist
                {
                    validPollExists = false;
                }
            }
      
            // Displays the question text
            private void BindQuestionText()
            {
                lblQuestionText.Text = questionText;
                lblQuestionText.Visible = true;
      
                if (questionHasMedia)
                {
                    BindQuestionImage();
                }
                else
                {
                    imgQuestion.Visible = false;
                    imgQuestionToolTip.Visible = false;
                }
            }
      
            // Displays question image if one is present
            private void BindQuestionImage()
            {
                var qpQuestionImage = (from qpi in contextVia.question_media
                                       where qpi.question_id == questionId
                                       select qpi).FirstOrDefault();
      
                string imageUrl = "~/UserControls/Picture.ashx?s=40&QID=" + questionId; // Small image
                string imageUrlTT = "~/UserControls/Picture.ashx?s=150&QID=" + questionId; // Larger, mouseover image
      
                imgQuestion.Visible = true;
                imgQuestionToolTip.Visible = true;
                imgQuestion.ImageUrl = System.Web.HttpUtility.HtmlDecode(imageUrl);
      
                questionToolTip.TargetControlID = imgQuestion.ID;
                imgQuestionToolTip.ImageUrl = System.Web.HttpUtility.HtmlDecode(imageUrlTT);
                imgQuestionToolTip.Height = 150;
                imgQuestionToolTip.Width = 150;
            }
      
            // Populates RadioButtonList, rdoQuickAnswer
            private void BindRdoQuickAnswer()
            {
                // Get all answers for this question (table answer_mcq)
                IList<answer_mcq> qpAnswers = DBUtility.GetAssessmentOptions(questionId);
      
                // Get IList of all student responses (each changed answer creates a new response) to this question
                IList<response> studentResponse = DBUtility.GetStudentResponses(studentClassId, assessmentQuestionId);
      
                // Clear rdoQuickAnswer item list. Avoids creating duplicates when Page_Load is hit twice
                rdoQuickAnswer.Items.Clear();
      
                for (int i = 0; i < qpAnswers.Count; i++) // For each student response to this question
                {
                    // Create a list item setting the question id as the value and the question text as the text
                    ListItem listItem = new ListItem();
                    listItem.Text = qpAnswers[i].option_text;
                    listItem.Value = qpAnswers[i].mcq_id.ToString();
                      
                    rdoQuickAnswer.Items.Add(listItem);
                      
                    string optionText = listItem.Text; // Variable to hold question text
      
                    if (Convert.ToBoolean(qpAnswers[i].has_image))
                    {
                        // Image path using the answer id as a query string value
                        string imageUrl = "~/UserControls/Picture.ashx?s=40&AIUID=" + qpAnswers[i].mcq_id;
      
                        // Create image object dynamically using imageUrl string
                        System.Web.UI.WebControls.Image answerImg = new System.Web.UI.WebControls.Image();
      
                        // Create full URL from string URL and assign it to the image object
                        answerImg.ImageUrl = Page.ResolveUrl(imageUrl);
      
                        // Apply HTML and CSS formatting to the ListItem text to properly display the image
                        listItem.Text += ("<div style=\"width: 50px; margin: 5px -20px 15px 0px; valign: middle;\"><img src='" + answerImg.ImageUrl + "' /></div>");
                        rdoQuickAnswer.Items[i].Text = listItem.Text;
                    }
                    else
                    {
                        // If no image, set style for the ListItem for consistency
                        listItem.Text = optionText + "<div style=\"width: 50px; margin: 5px 0px 15px 0px; valign: middle;\"></div>";
                    }
                }
      
                if (!isPollActive)
                    rdoQuickAnswer.Enabled = false;
      
                // If student has selected an option at least once
                if (studentResponse.Count > 0)
                {
                    // Get most recent student response
                    string answerMcq = studentResponse[0].mcq_answer_id.ToString().ToLower();
                      
                    // Set rdoQuickAnswer selected option to the student's most recent answer selection
                    for (int i = 0; i < rdoQuickAnswer.Items.Count; i++)
                    {
                        if (rdoQuickAnswer.Items[i].Value.ToLower().CompareTo(answerMcq) == 0)
                            rdoQuickAnswer.SelectedIndex = i;
                    }
                }
            }
      
            // Determines if poll is active
            private void SetCompletedStatus()
            {
                isPollActive = DBUtility.IsAssessmentActive(assessmentId);
            }
      
            // Sets lblMessage text
            private void SetMessages()
            {
                SetCompletedStatus();
      
                // Get IList of all student responses (each changed answer creates a new response) to this question
                IList<response> studentResponse = DBUtility.GetStudentResponses(studentClassId, assessmentQuestionId);
      
                if (studentResponse.Count > 0) // If student has responded
                {
                    if (isPollActive)
                    {
                        lblMessage.Text = "Currently selected answer is: " + rdoQuickAnswer.SelectedItem.Text;
                    }
                    else
                    {
                        lblTimerActiveTime.Text = "Completed";
                        lblMessage.Text = "Poll Completed: You selected: " + studentResponse[0].answer_text;
                    }
                }
                else // If student has not responded
                {
                    if (isPollActive)
                        lblMessage.Text = "You have not responded to this poll";
                    else
                        lblMessage.Text = "You did not respond to this poll";
                }
            }
      
            #endregion Private Methods
      
            #region Control Events
      
            protected void rdoQuickAnswer_SelectedIndexChanged(object sender, EventArgs e)
            {
                SetCompletedStatus();
                if (isPollActive)
                {
                    int index = Convert.ToInt32(ViewState["RdoQuickAnswerIndex"]);
                    ListItem li = rdoQuickAnswer.Items[index];
                    int mcqId = Convert.ToInt32(li.Value);
                    string mcqAnswerText = li.Text;
      
                    int responseCount = (from r in contextVia.responses
                                         where r.student_class_id == studentClassId
                                         && r.assesment_question_id == assessmentQuestionId
                                         select r.response_id).Count();
      
                    if (responseCount == 0)
                        InsertNewResponse(mcqId);
                    else
                        UpdateResponse(mcqId);
      
                    int selectedIndex = rdoQuickAnswer.SelectedIndex;
                    lblMessage.Text = "Currently selected answer is : \"" + mcqAnswerText + "\"";
                    rdoQuickAnswer.SelectedIndex = Convert.ToInt32(ViewState["RdoQuickAnswerIndex"]);
                    SetMessages();
                }
                else
                {
                    rdoQuickAnswer.Enabled = false;
                }
            }
      
            // Adds a response to the database if it is the student's first response
            private void InsertNewResponse(int mcqId)
            {
                // Get answer from DB based on currently selected mcq_id
                var answerMcq = (from amcq in contextVia.answer_mcq
                                 where amcq.mcq_id == mcqId
                                 select amcq).FirstOrDefault();
      
                // New student response object
                response qpResponse = new response();
      
                // Set response object's fields
                qpResponse.assesment_question_id = assessmentQuestionId;
                qpResponse.student_class_id = studentClassId;
                qpResponse.answer_text = answerMcq.option_text;
                qpResponse.is_correct = answerMcq.is_correct;
                qpResponse.mcq_answer_id = answerMcq.mcq_id;
                qpResponse.response_Date_Time = DateTime.UtcNow;
      
                // Save response to DB
                contextVia.responses.AddObject(qpResponse);
                contextVia.SaveChanges();
            }
      
            //Updates a student's response choice if one currently exists
            private void UpdateResponse(int mcqId)
            {
                // Get answer from DB based on currently selected mcq_id
                var answerMcq = (from amcq in contextVia.answer_mcq
                                 where amcq.mcq_id == mcqId
                                 select amcq).FirstOrDefault();
      
                var latestResponse = (from r in contextVia.responses
                                      where r.student_class_id == studentClassId
                                      && r.assesment_question_id == assessmentQuestionId
                                      orderby r.response_id descending
                                      select r).FirstOrDefault();
      
                latestResponse.mcq_answer_id = mcqId;
                latestResponse.answer_text = answerMcq.option_text;
                latestResponse.is_correct = answerMcq.is_correct;
                latestResponse.response_Date_Time = DateTime.UtcNow;
      
                contextVia.SaveChanges();
            }
      
            // TimerActiveTime: 5 second tick interval
            protected void TimerActiveTime_Tick(object sender, EventArgs e)
            {
                SetCompletedStatus();
      
                if (isPollActive)
                {
                    TimeSpan tickSpan = TimeSpan.Parse(lblTimerActiveTime.Text);
                    tickSpan = tickSpan.Add(TimeSpan.Parse(VConstants.QUICK_POLL_FREQUENCY));
                    lblTimerActiveTime.Text = tickSpan.ToString();
                }
                else
                {
                    SetMessages();
                    TimerActiveTime.Enabled = false;
                    rdoQuickAnswer.Enabled = false;
                    lblTimerActiveTime.Text = "Completed";
                }
            }
      
            // Refresh chart control (currently unused)
            protected void imgBtnRefresh_Click(object sender, ImageClickEventArgs e)
            {
      
            }
      
            // Chart control (currently unused)
            protected void chartQuickPoll_Customize(object sender, EventArgs e)
            {
      
            }
      
            #endregion Control Events
        }
    }


    Thanks for your time!
                              Derrick
  2. Iana Tsolova
    Admin
    Iana Tsolova avatar
    3388 posts

    Posted 15 Nov 2011 Link to this post

    Hello Derrick,

    I suggest that you revise the ajax settings and make sure that the only the controls that really should be updated are added as UpdatedControls.

    Check it out and let me know how it goes.

    Greetings,
    Iana Tsolova
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
Back to Top