I have a Repeater
that contains a link labeled "Change Membership" that when clicked opens a lightbox with a radiobuttonlist
and a button
. When the button in the lightbox is clicked I have a callback event where I need to find the selected value of the radiobutton list first here is the repeater:
<script language="JavaScript" type="text/javascript">
function CreateBox(id) {
$(document).ready(function () {
$("#lnk" + id).fancybox({
'closeBtn': true,
helpers: {
overlay: { closeClick: false }
}
});
});
}
</script>
<asp:Repeater ID="repProspects" runat="server" OnItemDataBound="repProspects_ItemDataBound">
<ItemTemplate>
<asp:HiddenField ID="hfRequestID" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.RequestID") %>' />
<asp:HiddenField ID="hfRecruiterNumber" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.RecruiterCardNumber") %>' />
<asp:HiddenField ID="hfCompanyID" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.CompanyID") %>' />
<asp:HiddenField ID="hfMemberType" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.MemberType") %>' />
<asp:HiddenField ID="hfLifeDuesAmount" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.Dues") %>' />
<asp:HiddenField ID="hfDerivedAnnualDues" runat="server" />
<asp:HiddenField ID="hfDerivedInstallments" runat="server" />
<asp:HiddenField ID="hfRblSelectedValue" runat="server" />
<asp:HiddenField ID="hfSetMemberType" ClientIDMode="Static" runat="server" />
<asp:HiddenField ID="hfState" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.HomeState") %>' />
<asp:HiddenField ID="hfCountry" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.HomeCountry") %>' />
<asp:HiddenField ID="hfBirthday" runat="server" Value='<%# DataBinder.Eval(Container, "DataItem.Birthday") %>' />
<div id='h<%# DataBinder.Eval(Container, "DataItem.ID") %>' class="header" onclick='ToggleDisplay(<%# DataBinder.Eval(Container, "DataItem.ID") %>);'>
<img id="img<%# DataBinder.Eval(Container, "DataItem.ID") %>" alt="" src="../images/plusIconSmaller.png" />
<%# DataBinder.Eval(Container, "DataItem.FirstName")%>
<% if (DataBinder.GetDataItem("DataItem.MiddleName") != "")
{ %>
<%# DataBinder.Eval(Container, "DataItem.MiddleName")%>
<% } %>
<%# DataBinder.Eval(Container, "DataItem.LastName")%>
<% if (DataBinder.GetDataItem("DataItem.Suffix") != "")
{ %>
<%# DataBinder.Eval(Container, "DataItem.Suffix")%>
<% } %>
(<%# DataBinder.Eval(Container, "DataItem.CurrentStatus")%>, <%# DataBinder.Eval(Container, "DataItem.BranchOfService")%>)
<asp:Label ID="lblRecruitedBy" runat="server"></asp:Label>
<%# Convert.ToDateTime(DataBinder.Eval(Container, "DataItem.DateCreated")).ToShortDateString()%>
</div>
<div id='reqid<%# DataBinder.Eval(Container, "DataItem.RequestID") %>'></div>
<div id='d<%# DataBinder.Eval(Container, "DataItem.ID") %>' class="details">
<table width="100%">
<tr>
<td valign="top" width="25%"><u><b>Address</b></u><br />
<%# DataBinder.Eval(Container, "DataItem.HomeAddressLine1")%><br />
<%# DataBinder.Eval(Container, "DataItem.HomeCity")%>, <%# DataBinder.Eval(Container, "DataItem.HomeState")%> <%# DataBinder.Eval(Container, "DataItem.HomeZipCode")%><br />
<%# DataBinder.Eval(Container, "DataItem.HomeCountry")%></td>
<td valign="top" width="20%"><u><b>Qualifying Service</b></u><br />
<asp:Label ID="lblServiceInfo" runat="server"></asp:Label></td>
<td valign="top" width="20%"><u><b>Contact Info</b></u><br />
<% if (DataBinder.GetDataItem("DataItem.Phone") != "")
{ %>
<%# FormatPhone(DataBinder.Eval(Container, "DataItem.Phone").ToString()) %>
<% } %>
<asp:Label ID="lblMemberPhone" runat="server"></asp:Label>
<%# DataBinder.Eval(Container, "DataItem.Email")%><br />
Birthday: <%# Convert.ToDateTime(DataBinder.Eval(Container, "DataItem.Birthday")).ToShortDateString()%></td>
<td valign="top" width="20%"><u><b>Membership</b></u><br />
<%# DataBinder.Eval(Container, "DataItem.MemberType")%><br />
$<asp:Label ID="lblDuesAmount" runat="server"></asp:Label>
<br />
<a href='#ChgMemType<%# DataBinder.Eval(Container, "DataItem.ID") %>' onclick='CreateBox(<%# DataBinder.Eval(Container, "DataItem.ID") %>);' id='lnk<%# DataBinder.Eval(Container, "DataItem.ID") %>' >Change Membership</a>
</td>
<td valign="top" align="center">
<asp:Button ID="lnkApprove" Style="border: 1px solid black; border-radius: 7px; padding: 5px; cursor: pointer; background-color: #990000; width: 130px; color: white; font-weight: bold" Text="Approve & Pay" runat="server" CommandArgument='<%# DataBinder.Eval(Container, "DataItem.ID") %>' OnClientClick="return confirm('Are you sure you want to approve this member application?');" OnCommand="lnkApprove_Click"></asp:Button><br />
<br />
<asp:Button ID="lnkReject" Style="border: 1px solid black; border-radius: 7px; padding: 5px; cursor: pointer; background-color: #990000; width: 130px; color: white; font-weight: bold" Text="Reject" runat="server" CommandArgument='<%# DataBinder.Eval(Container, "DataItem.ID") %>' OnClientClick="return confirm('Are you sure you want to reject this member applictation?');" OnCommand="lnkReject_Click"></asp:Button></td>
</tr>
</table>
</div>
<div id='ChgMemType<%# DataBinder.Eval(Container, "DataItem.ID") %>' style="display: none; width:400px; text-align: left">
<h3>Change Membership Type </h3>
<p>Please select the membership type below:</p>
<input id='hfChangedMemberType' value="<%# DataBinder.Eval(Container, "DataItem.ID") %>" type="hidden" />
<div id="RadioDiv">
<asp:RadioButtonList ID="_rblMemberTypes" runat="server">
<asp:ListItem Text="Annual" Value="Annual">Annual</asp:ListItem>
<asp:ListItem Text="Life" Value="Life">Life</asp:ListItem>
<asp:ListItem Text="Installment" Value="Installment">Installment</asp:ListItem>
</asp:RadioButtonList>
</div>
<asp:LinkButton ID="lbSetMemType" EnableViewState="true" CommandArgument='<%# DataBinder.Eval(Container, "DataItem.RequestID") %>' OnCommand="lbSetMemType_Command" CssClass="button" runat="server">Save</asp:LinkButton>
</div>
</ItemTemplate>
</asp:Repeater>
Next is the code behind event when the Save button is clicked:
protected void lbSetMemType_Command(object sender, CommandEventArgs e)
{
decimal dDuesAmount = 0;
bool bSuccess = false;
int iRequestID = Convert.ToInt32(e.CommandArgument);
string sMemType = "";
HiddenField hfDerivedAnnualDues;
HiddenField hfDerivedInstallments;
HiddenField hfLifeDuesAmount;
HiddenField hfSetMemberType;
foreach (RepeaterItem item in repProspects.Items)
{
// Checking the item is a data item
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var reqid = item.FindControl("hfRequestID") as HiddenField;
if (Convert.ToInt32(reqid.Value) == iRequestID) {
var rdbList = item.FindControl("_rblMemberTypes") as RadioButtonList;
if (rdbList != null)
{
foreach (ListItem li in rdbList.Items)
{
if (li.Selected == true)
{
sMemType = li.Text;
}
}
}
// Get the selected value
hfSetMemberType = item.FindControl("hfRblSelectedValue") as HiddenField;
sMemType = rdbList.SelectedValue;
// sMemType = hfSetMemberType.Value;
hfDerivedAnnualDues = item.FindControl("hfDerivedAnnualDues") as HiddenField;
hfDerivedInstallments = item.FindControl("hfDerivedInstallments") as HiddenField;
hfLifeDuesAmount = item.FindControl("hfLifeDuesAmount") as HiddenField;
}
}
}
switch (sMemType)
{
case "Annual":
{
//dDuesAmount = Convert.ToDecimal(hfDerivedAnnualDues.Value);
break;
}
case "Life":
{
//dDuesAmount = Convert.ToDecimal(hfLifeDuesAmount.Value);
break;
}
case "Installments":
{
// dDuesAmount = Convert.ToDecimal(hfDerivedInstallments.Value);
break;
}
default:
{
//dDuesAmount = Convert.ToDecimal(hfDerivedAnnualDues.Value);
break;
}
}
bSuccess = logicManager.UpdateNewMemberAppMemType(iRequestID, sMemType, dDuesAmount);
}
I can set breakpoints and I can see the values in the hiddenfields are correct however I can't get the right clicked value on this statement:
sMemType = rdbList.SelectedValue;
I get the initial value but not the user clicked value?
First, you're missing OnItemCommand="lbSetMemType_Command"
in your actual code.
Also, iterating through your repeater by hand will give you poor performance result, especially if you're looking for just the value of a radiobutton.
Now, lets do a MCVE example together. According to your code, you're trying to build a RadioButtonList
inside a Repeater
, with a LinkButton
who use the radio's button value. In our case, let's just print the value of said choosen button in a label, proving our case.
MCVE.aspx
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<asp:Repeater ID="rptTest" runat="server" OnItemCommand="rptTest_ItemCommand">
<ItemTemplate>
<asp:RadioButtonList ID="rdlTest" runat="server">
<asp:ListItem Text="Annual" Value="Annual"></asp:ListItem>
<asp:ListItem Text="Life" Value="Life"></asp:ListItem>
<asp:ListItem Text="Installment" Value="Installment"></asp:ListItem>
</asp:RadioButtonList>
<asp:LinkButton runat="server" ID="lbValidationTest" OnClick="lbValidationTest_Click" runat="server" >Fetch Value</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
<asp:Label runat="server" ID="lblViewResult"></asp:Label>
</asp:Content>
I'm using the default masterpage when you create a new project on VS. It really doesnt matter here
And the codebehind
MCVE.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication
{
public partial class MCVE: Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> uselessData = new List<int>(new int[] { 1, 2 });
this.rptTest.DataSource = uselessData;
this.rptTest.DataBind();
}
}
protected void rptTest_ItemCommand(object source, RepeaterCommandEventArgs e)
{
RadioButtonList list = (RadioButtonList)e.Item.FindControl("rdlTest");
this.lblViewResult.Text = list.SelectedValue;
}
}
}
After some tries, we clearly see that this is not working as intended. There is in fact some known issues between the Repeater
& the RadioButtonList
forbidding us to do just that.
So, what to do now ? We have plenty of solutions, we can for example use javascript to get and set our values in a hidden field ; we could iterate through or entire repeater tree and check every button or even use the CommandArgument
to locate the RadioButtonList
's index and fetch it in codebehind.
Let's implement the javascript solution. We are going to inject the value of our index in a hidden field present in the repeater. I think its better to treat this behaviour client side rather than server-side, but I could be mistaken and would love some output on this.
So let's add a very dirty javascript code to our view
MCVE.aspx New Version
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<asp:Repeater ID="rptTest" runat="server" OnItemCommand="rptTest_ItemCommand">
<ItemTemplate>
<div>
<asp:HiddenField runat="server" ID="hfSelectedValue" />
<asp:RadioButtonList ID="rdlTest" runat="server" >
<asp:ListItem Text="Annual" Value="Annual" onclick="QuickAndDirtyHiddenSetDontUseItInProd(this)"></asp:ListItem>
<asp:ListItem Text="Life" Value="Life" onclick="QuickAndDirtyHiddenSetDontUseItInProd(this)"></asp:ListItem>
<asp:ListItem Text="Installment" Value="Installment" onclick="QuickAndDirtyHiddenSetDontUseItInProd(this)"></asp:ListItem>
</asp:RadioButtonList>
<asp:LinkButton runat="server" ID="lbValidationTest" runat="server" UserSubmitBehavior="true" >Fetch Value</asp:LinkButton>
</div>
</ItemTemplate>
</asp:Repeater>
<asp:Label runat="server" ID="lblViewResult"></asp:Label>
<script>
function QuickAndDirtyHiddenSetDontUseItInProd(data) {
$(data).parent().parent().parent().parent().siblings("input[name*=hfSelectedValue]").val(data.value);
}
</script>
</asp:Content>
We just changed 3 things. We're going to track a hidden field for each radiobuttonlist we're going to create, we added a script to change the value of said hidden field and linked the two with the onclic.
Now, on our codebehind, we just have to track the hidden field grouped with the click on the ButtonLink (ie, in the same RepeaterItem
) and we're good to go.
MCVE.aspx.cs New Version
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication
{
public partial class MCVE: Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> uselessData = new List<int>(new int[] { 1, 2 });
this.rptTest.DataSource = uselessData;
this.rptTest.DataBind();
}
}
protected void rptTest_ItemCommand(object source, RepeaterCommandEventArgs e)
{
HiddenField hiddenField = (HiddenField)e.Item.FindControl("hfSelectedValue");
this.lblViewResult.Text = hiddenField.Value;
}
}
}
Pretty Self-explanatory, we just find the hidden field in our repeater, and we use it to fill the label.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With