Найти выбранное значение RadioButton внутри лайтбокса внутри ретранслятора

У меня есть Repeater содержит ссылку "Изменить членство", которая при нажатии открывает лайтбокс с radiobuttonlist и button, Когда кнопка в лайтбоксе нажата, у меня возникает событие обратного вызова, в котором мне нужно сначала найти выбранное значение из списка радиокнопок: вот повторитель:

  <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")%>)&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>

Далее идет код события после нажатия кнопки "Сохранить":

        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);
        }

Я могу установить точки останова, и я вижу, что значения в скрытых полях верны, однако я не могу получить правильное значение для этого оператора:

sMemType = rdbList.SelectedValue;

Я получаю начальное значение, но не пользователь нажал значение?

1 ответ

Во-первых, ты скучаешь OnItemCommand="lbSetMemType_Command" в вашем реальном коде. Кроме того, итерация вашего повторителя вручную даст вам плохой результат, особенно если вы ищете только значение радиопереключателя.

Теперь давайте вместе сделаем пример MCVE. Согласно вашему коду, вы пытаетесь построить RadioButtonList внутри Repeater с LinkButton кто использует значение кнопки радио. В нашем случае, давайте просто напечатаем значение выбранной кнопки в метке, подтверждая наш случай.

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>

Я использую мастер-страницу по умолчанию, когда вы создаете новый проект на VS. Это действительно не имеет значения здесь

И код позади

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;
        }
    }
}

После некоторых попыток мы ясно видим, что это работает не так, как задумано. На самом деле есть некоторые известные проблемы между Repeater & RadioButtonList запрещающий нам делать именно это.

Итак, что теперь делать? У нас есть много решений, мы можем, например, использовать javascript, чтобы получить и установить наши значения в скрытом поле; мы могли бы пройти через или все дерево повторителей и проверить каждую кнопку или даже использовать CommandArgument найти RadioButtonList Индекс и получить его в коде позади.

Давайте реализуем решение JavaScript. Мы собираемся ввести значение нашего индекса в скрытое поле, присутствующее в репитере. Я думаю, что лучше относиться к такому поведению на стороне клиента, а не на стороне сервера, но я могу ошибаться и хотел бы получить некоторую информацию по этому вопросу.

Итак, давайте добавим очень грязный код JavaScript на наш взгляд

MCVE.aspx Новая версия

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

Мы только что изменили 3 вещи. Мы собираемся отследить скрытое поле для каждого списка радиокнопок, который мы собираемся создать, мы добавили скрипт для изменения значения указанного скрытого поля и связали их с онкликом.

Теперь, в нашем коде, нам просто нужно отследить скрытое поле, сгруппированное с помощью нажатия на ButtonLink (т.е. в том же RepeaterItem) и нам пора.

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)
        {
            HiddenField hiddenField = (HiddenField)e.Item.FindControl("hfSelectedValue");
            this.lblViewResult.Text = hiddenField.Value;
        }

    }
}

Довольно очевидно, мы просто находим скрытое поле в нашем репитере и используем его для заполнения метки.

Другие вопросы по тегам