RadioButtonList每次都不会触发SelectedIndexChanged

时间:2016-10-07 12:13:41

标签: javascript jquery asp.net telerik

我有一个RadioButtonList,其中包含“Not Applicable”,“Not Available”,“Leave”和“Available”选项。

  1. 我在服务器端的RadioButtonList点击“离开”时抛出确认信息框,如下所示

    protected void rdlUser_SelectedIndexChanged(object sender, EventArgs e)
    {
        radWindowManager.RadConfirm("Are you sure you want to take leave?", "confirmLeave" + this.ClientID, 300, 100, null, "");
    }
    
  2. 如果用户点击“取消”,则会自动选择“可用”,代码如下。

  3. 以下是“Ok”或“Cancel”的javascript代码。

        function confirmLeave<%=this.ClientID%>(arg) {
            if (arg == true) {
                alert("User has selected Leave.")
            }    
            else {
                var rdlUser = docment.getElementById("<%= rdlUser.ClientID %>");
                var radioButtons = rdlUser.getElementsByTagName('input');
                radioButtons[1].checked = true;
            }
        }
    

    如果用户第二次点击“离开”,则根本不会触发SelectedIndexChanged。

    我可以灵活地将服务器端代码移动到客户端。

    更新

    以下是相关的HTML代码

    <table id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser">
    <tr>
        <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_0" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT01" disabled="disabled" onclick="javascript:setTimeout(&#39;__doPostBack(\&#39;ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser$0\&#39;,\&#39;\&#39;)&#39;, 0)" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_0">Not Applicable</label></span></td>
        <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_1" class="Leave" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT02" onclick="javascript:setTimeout(&#39;__doPostBack(\&#39;ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser$1\&#39;,\&#39;\&#39;)&#39;, 0)" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_1">Not Available</label></span></td>
    </tr><tr>
        <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_2" class="Leave" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT03" onclick="javascript:setTimeout(&#39;__doPostBack(\&#39;ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser$2\&#39;,\&#39;\&#39;)&#39;, 0)" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_2">Leave</label></span></td>
    </tr><tr>
        <td><span class="available"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_3" class="Available" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT04" checked="checked" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_3">Available</label></span></td>
    </tr>
    

    更新2

    我被困在这里 - 我需要将RadioButtonList的this.ClientID指向jQuery的$ this。而已。在那里,我可以执行@smoksnes提供的第二个答案

    更新3

    如果用户选择“不可用”或“离开”,那么它应该抛出错误消息“你想要离开吗?”如果他选择“取消”,那么RadioButtonList的选择应该指向“可用”。否则应相应选择“不可用”或“离开”。

2 个答案:

答案 0 :(得分:2)

因为您对将代码移动到客户端的idéa持开放态度。移除radiobutton上的OnSelectedIndexChange以跳过回发。你应该可以做这样的事情:

// Put this in a script-tag.
$(document).ready(function(){
    $('#<%=this.ClientID%>').change(function(){
        var radioBtnId = this.id;
        radconfirm('Are you sure you want to take leave?', function(arg){
            if (arg == true) {
                alert("User has selected Leave.")
            }    
            else {
                var rdlUser = docment.getElementById(radioBtnId);
                var radioButtons = rdlUser.getElementsByTagName('input');
                radioButtons[1].checked = true;
            }
         }
        });
    });
})

以下是使用没有服务器代码的ID的代码段。

$('#radio1').change(function(e){
  var radioBtnId = this.id;
  var $this = $(this);
  radconfirm('Are you sure you want to take leave?', function(arg){
    // Not really sure what you want to do here...
    if (arg == true) {
      alert("User has selected Leave.")
    }    
    else {
      // Select "Available instead".
      $this.siblings('input').prop('checked',true);
      
      // Unselect "Leave"
      
      // With javascript
      var rdlUser = document.getElementById(radioBtnId);              
      rdlUser.checked = false;
      
      // With jQuery
      $this.prop('checked', false);
    }
  });
});
    
// Mocked for now...
function radconfirm(value, callback){
  var result = confirm(value);
  callback(result);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="radio" name="radios" id="radio1" value="Leave"/> <label for="radio1" >Leave</label>
<input type="radio" name="radios" id="radio2" value="Available"/> <label for="radio2" >Available</label>

<强>更新 我已经更新了脚本以适应新的HTML。在这里,我们将事件绑定到星期一控件。请注意,您可能希望在控件上设置CssClass而不是使用ID。然后,您可以对所有控件使用相同的脚本(MyMonday,MyTuesday等)。它看起来像这样:

<asp:MyControl CssClass="day-control" runat="server" id="MyMondayControl" />

如果是这样,您应该能够将以下脚本更改为:

$('.day-control input').change....

否则您需要使用clientID。

$('#<% MyMondayControl.ClientID %> input').change ....
  

不知道为什么onclick =“javascript:setTimeout”正在添加   HTML

那是因为您使用AutoPostBack的服务器控件作为您的无线电按钮。删除它,你应该没事。请在this question中了解详情。

在下面的代码片段中,我冒昧地将CSS类分配给不同的radiobuttons。一个人将决定何时运行“check if leave”-script。一个是知道用户选择留下哪个单选按钮。 css类是leave-checkselect-if-not-leave。您可以使用CssClass属性添加它们。

您可能还想查看呈现的HTML。您提供的HTML使用tabletr,因此请确保实际在input上呈现css类。否则你需要调整选择器。

// Change to the id of the table instead. Something like:
// $('#<% MyMondayControl.ClientID %> input').change ....

// Here I just the ID generated in the HTML, but you shouldn't use that one.
$('#ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser span.leave input').change(function(e){
  e.preventDefault();
  var radioBtnId = this.id;
  var $this = $(this);
  radconfirm('Are you sure you want to take leave?', function(arg){
    // Not really sure what you want to do here...
    if (arg == true) {
      alert("User has selected Leave.")
    }    
    else {
      // Select "Available instead".
      // Here we use the css class "select-if-not-leave" to find the element which should be selected if the user decides to stay.
      var $parent = $this.closest('table') // Get the table. 
      
      // Select the available input.
      $parent.find('span.available input').prop('checked',true);
      
      // Unselect "Leave" With javascript
      var rdlUser = document.getElementById(radioBtnId);              
      rdlUser.checked = false;
      
      // Unselect "Leave" With jQuery (You only need one)
      $this.prop('checked', false);
    }
  });
});
    
// Mocked for now...
function radconfirm(value, callback){
  var result = confirm(value);
  callback(result);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser">
  <tr>
    <tr>
    <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_0" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT01" disabled="disabled"  /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_0">Not Applicable</label></span></td>
    <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_1" class="Leave" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT02" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_1">Not Available</label></span></td>
</tr><tr>
    <td><span class="leave"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_2" class="Leave" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT03"/><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_2">Leave</label></span></td>
</tr><tr>
    <td><span class="available"><input id="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_3" class="Available" type="radio" name="ctl00$ContentPlaceHolder1$MyUser$MyMonday$rdlUser" value="SLOT04" checked="checked" /><label for="ctl00_ContentPlaceHolder1_MyUser_MyMonday_rdlUser_3">Available</label></span></td>
</tr>
</table>

更新2:

  
      
  1. 当我在Day UserControl中编写jQuery脚本时,我只能使用.leave和.available类,但不能使用.day-control。我写的时候   UserControl中的jQuery脚本MyMonday,MyTuesday,...   MyFriday被声明,然后我只能使用.day-control但不能使用.leave   和.available类。 @smoksnes请解决这个含糊不清的问题。
  2.   

你把脚本放在哪里无所谓,只要脚本看起来一样。最好将它与其他脚本一起放在js文件中。以下是脚本和jQuery selectors如何工作的一些信息:

如果您使用.day-control span.available input,则会首先查找css class day-control的某个元素,以及span WITH css-class {{1最后是available下的input。如果有几个元素符合我刚刚提到的标准,它将返回所有这些元素。此脚本只应呈现,因为它会捕获所有span的事件,因为它们共享相同的css类DayUserControl

但是,如果您使用day-control,则会首先查找带有specific id#<%=this.ClientID%> span.leave input)的元素,并且应该只有其中一个元素。这就是为什么你需要为每个 this.ClientID渲染一次特定的脚本,因为它对于那个特定的用户控件来说是唯一的。

答案 1 :(得分:0)

将调用者对象传递给radconfirm函数。(http://docs.telerik.com/devtools/aspnet-ajax/controls/window/alert,-confirm,-prompt-dialogs/radconfirm-dialog)。

从服务器传递调用者对象 protected void rdlUser_SelectedIndexChanged(object sender, EventArgs e) { //var oConfirm = radconfirm(text, callBackFn, oWidth, oHeight, callerObj, oTitle, imgUrl); radWindowManager.RadConfirm("Are you sure you want to take leave?", "confirmLeave", 300, 100, null, ""); }

一个javascript函数,用于验证列表中的所有控件。

function confirmLeave(arg) { if (arg == true) { alert("User has selected Leave.") }
else { //get callerid and validate var rdlUser = docment.getElementById("<%= rdlUser.ClientID %>"); var radioButtons = rdlUser.getElementsByTagName('input'); radioButtons[1].checked = true; } }

我提到了文档,我没有测试这段代码,希望这会有所帮助。