开发者

Event handlers for controls in an ASP Repeater

I need to be able to trigger events when a user clicks on a radio button that is generated within an control on my page.

I've added an OnSelectedIndexChanged handler to the RadioButtonList and created a function in my code behind that should handle the selection of the RadioButtonList's ListItems, but I don't know how to pass a value to that function. Here's my code:

<asp:Repeater runat="server" ID="rptQuestions">
    <HeaderTemplate><table width="100%"></HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td colspan="2"><%# Container.DataItem("QuestionText")%></td>
        </tr>
        <tr>
            <td>
                <asp:RadioButtonList runat="server" ID="rblAnswerSelection" RepeatDirection="Horizontal" AutoPostBack="true" OnSelectedIndexChanged="CheckAnswer">
                    <asp:ListItem Text="True" Value="1"></asp:ListItem>
                    <asp:ListItem Text="False" Value="0"></asp:ListItem>
                </asp:RadioButtonList>
                <asp:Label runat="server" ID="lblCorrectAnswer" Text="<%#Container.DataItem("CorrectAnswer") %>"></asp:Label>
            </td>
            <td><asp:Label runat="server" ID="lblResult"></asp:Label></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate></table></FooterTemplate>
</asp:Repeater>

Private Function CheckAnswer(ByVal SelectedAnswer As Integer) As Boolean
    Select Case Selected开发者_如何学运维Answer
        Case 1 ' User answered True
            If lblCorrectAnswer.Text = "True" Then
                Return True
            Else
                Return False
            End If
        Case 0 ' User answered False
            If lblCorrectAnswer.Text = "False" Then
                Return True
            Else
                Return False
            End If
    End Select
End Function

The idea is that the user is to be informed whether or not their selected answer was correct. The value of the CheckAnswer function would determine a "CORRECT" or "INCORRECT" message displaying on lblResult. If there's a way to do this without a PostBack, then that would be ideal.

Any suggestions will be greatly appreciated.


Here's brief outline of client side solution (w/o post-back). Use html radio-buttons along with a hidden field to store the correct answer. Attach click event handlers on radio-buttons to match the value with the value from hidden field.

Repeater Mark-up:

    <tr>
        <td colspan="2"><%# Container.DataItem("QuestionText")%></td>
    </tr>
    <tr>
        <td class="answerContainer">
            <input type="radio" class="option" name='answer_<%# Container.ItemIndex %>' value="1">True
            <input type="radio" class="option" name='answer_<%# Container.ItemIndex %>' value="0">False                
            <input type="hidden" id="correct_answer" value='<%#Container.DataItem("CorrectAnswer") %>' />
        </td>
        <td>
            <span class="result" />
        </td>
    </tr>

Java-script (using jquery):

$(document).ready(function() {

  $('td.answerContainer .option').click(function() {   
      var opt = $(this);
      var correctAns = opt.next('#correct_answer');
      var result = (opt.val() == correctAns.val()) ? "Correct" : "Incorrect";
      opt.parent().next('td').find('.result').html(result);
  });

});

Disclaimer: untested code

Note that radio button names are suffixed with the item index so that on the server side, you can read the user's answers by looking into the request (for example, value of Request["answer_1"] should tell user selected answer for second question -> "1" : True, "0": False and empty string: no selection).

The obvious disadvantage is that correct answer is stored in the html and so it will be simpler to cheat the system. Solution can be to make ajax call to the server to check if the answer is correct or not - this will need creating salted time-bound pseudo-random tokens to identify questions (otherwise user can make same ajax calls to get answers).


Cut your RadioButton code from repeater somewhere outside repeater, go to Design view and click on that RadioButton (now it's not included in repeater and you can assign event handler to it without typing any code manually).

When you select this RadioButton in DesignView, click events button in your proporties tab and click OnSelectedIndexChanged and this will auto generate eventhandler function. You have to enable autopostback on this radiobutton (arrow in top right corner of control - in Design view).

Now cut back this RadioButton and place it inside your repeater. Now every radiobutton change will cause calling generated handler function where you can cast sender object to RadioButton, and you can access its value with SelectedValue property.

I've tried this solution many times, but only in C# so I am sorry if something is different in VB.NET


You can't use Function as an event handler. It must be a sub which takes two argument.

Take a look at this sample.

Markup

<asp:Repeater runat="server" ID="rptQuestions">
<HeaderTemplate><table width="100%"></HeaderTemplate>
<ItemTemplate>
    <tr>
        <td colspan="2"><%# Eval("Name")%></td>
    </tr>
    <tr>
        <td>
            <asp:RadioButtonList runat="server" 
               ID="rblAnswerSelection" 
               RepeatDirection="Horizontal" 
               AutoPostBack="true" 
               OnSelectedIndexChanged="CheckAnswer">
                <asp:ListItem Text="True" Value="1"></asp:ListItem>
                <asp:ListItem Text="False" Value="0"></asp:ListItem>
            </asp:RadioButtonList>
            <asp:Label runat="server" 
                 ID="lblCorrectAnswer" 
                 Text='<%#Eval("CorrectAnswer") %>'>
            </asp:Label>
        </td>
        <td><asp:Label runat="server" ID="lblResult"></asp:Label></td>
    </tr>
</ItemTemplate>
<FooterTemplate></table></FooterTemplate>
</asp:Repeater>

Code-behind

 Public Class Data
        Public Property QuestionText As String
        Public Property CorrectAnswer As String
    End Class

    Dim lst As List(Of Data)
    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            lst = New List(Of Data)
            lst.Add(New Data() With {.QuestionText = "A", .CorrectAnswer = "True"})
            lst.Add(New Data() With {.QuestionText = "B", .CorrectAnswer = "False"})
            lst.Add(New Data() With {.QuestionText = "C", .CorrectAnswer = "True"})

            rptQuestions.DataSource = lst
            rptQuestions.DataBind()
        End If
    End Sub

    Protected Sub CheckAnswer(sender As Object, e As System.EventArgs)
        Dim rad As RadioButtonList = DirectCast(sender, RadioButtonList)
        Dim item As RepeaterItem = DirectCast(rad.Parent, RepeaterItem)
        Dim correctAns As Label = DirectCast(item.FindControl("lblCorrectAnswer"), Label)
        Dim result As Label = DirectCast(item.FindControl("lblResult"), Label)
        Dim SelectedAnswer As String = rad.SelectedItem.Text
        If correctAns.Text = SelectedAnswer Then
            result.Text = "Correct"
        Else
            result.Text = "Incorrect"
        End If
    End Sub
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜