Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the selected value of a RadioButton inside a Lightbox that is inside a Repeater

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>

Head

Body

   <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")%>)&nbsp;&nbsp;
            <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")%>&nbsp;<%# 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?

like image 723
Lyle Avatar asked Nov 09 '22 14:11

Lyle


1 Answers

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 RadioButtonListforbidding 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.

like image 130
Mekap Avatar answered Nov 14 '22 21:11

Mekap