2012-09-10 86 views
1

我正在使用jQuery选择器来隐藏和取消隐藏一些动态生成的HTML单元格。但是,似乎我没有选择正确的选择器。所以,如果你能给我一些建议,我很感激。jQuery选择器无法正常工作

该网页:

  1. 首先询问用户选择的基础上用户选择的应用程序
  2. 数,生成两个输入字段“应用程序的定时”,和“申请日期”的每个应用程序。
  3. “应用程序计时”中有两个选项。如果用户选择“默认”,则“申请日期”将消失。

问题: 当有三个以上的应用程序,只有最后的“申请日期”将消失,不管在那里做出选择。我认为这是因为我没有使用正确的选择器。

DEMO

HTML代码

<table class="table"> 
    <tr> 
     <th> 
      <label for="id_NOA">Number of applications:</label> 
     </th> 
     <td> 
      <select id="id_NOA" class="valid" name="NOA"> 
       <option selected="selected" value="">Choose</option> 
       <option value="1">1</option> 
       <option value="2">2</option> 
       <option value="3">3</option> 
       <option value="4">4</option> 
      </select> 
     </td> 
    </tr> 
</table> 

的JavaScript

$(document).ready(function() { 
    $('#id_NOA').change(function() { 

     var total = $(this).val(); 
     $('.app_timing').remove(); 
     $('.app_dates').remove(); 

     for (var i = 1; i <= total; i++) { 

      $('<tr class="app_timing"><th><label for="id_Apt' + i + '">Application timing ' + i + ':</label></th><td><select name="Apt' + i + '" id="id_Apt' + i + '"><option value="" selected="selected">Select an application timing</option><option value="1">Default</option><option value="2">Enter your own</option></select></td></tr>').appendTo('.table') 

      $('<tr class="app_dates"><th><label for="id_Date_apt">Application Date ' + i + ':</label></th><td><input readonly="readonly" type="text" name="Date_apt' + i + '" value="MM/DD" id="id_Date_apt' + i + '"/><td></tr>').appendTo('.table') 

      $('.app_timing:last').find('select').bind('change', function() { 
       if ($(this).val() == '1') { 
        $('.app_dates:last').hide() 
       //$('#id_Date_apt' + i).hide() //I tried to use ID selector, but it does not work 
       } 

      }) 
     } 
    }) 


})​ 
+0

您正在特别选择最后一个app_date。使用'$('。app_dates')'而不是'$('。app_dates:last')'来选择它们全部。 –

+0

作为@NickG。说,虽然你在for循环中绑定了多个相同函数的事件,但认为最好在循环外部使用它。 – dbf

+0

@Boltclock:问题是垃圾 - “jQuery选择器无法正常工作”,这确实没有问题。有些东西要求提出建议并指出问题。 '是的确如此.'对于标题/问题 – vol7ron

回答

4
$('.app_dates:last').hide() 

上面一行是change处理程序中,直到该处理程序火灾不执行。在它触发的时候,这会得到最后一个元素,这会导致你观察到的行为。您可以使用以下内容:

$(this).closest("tr").next().hide() 

请注意,这是基于您当前的html。改变将需要改变。它只是隐藏表格中的下一行。

编辑:

虽然上述答案的问题,总的更好的方法是使用event delegation。这将允许您附加单个处理程序,而不是每次更改下拉列表时创建新的处理程序。(请注意,我添加了一个类向每个选择以简化选择器)

$(".table").on("change",".timeSel",function(){ 
    var $this = $(this); 

    if ($this.val() == '1') { 
     $(this).closest("tr").next().hide(); 
    } 
}); 

http://jsfiddle.net/JDFcn/11/

+0

谢谢詹姆斯。有一个问题,我可以将选择器添加到下一个括号中,对吗?(例如next(jQuery选择器)) –

+0

@ tao.hong但是,您可以将它放在下一个元素之外。 –

3

更换

$('.app_dates:last').hide() 

$(this).closest('.app_timing').next().hide() 

:last或使用i不会工作,因为这样的事实,整个for循环已经通过迭代后的事件发生。

+1

'.app_dates'不是选择的祖先。 –

+0

@JamesMontagne谢谢,修正。 –

+0

感谢您的帮助! –

2

尝试:

$('.app_timing:last').find('select').on('change', function() { 
    if ($(this).val() == '1') { 
     $(this).parents('tr').next('.app_dates').remove(); 
    } 
}) 

jsFiddle example

这将删除该行下面你更改为 “默认” 行。它沿DOM向上移动,然后再向下移动以找到要移除的行。

0

当你的功能被调用时,它试图访问变量已经左递增到1更比你在顶部下拉菜单中选择的数量要多,所以你不能使用它。您的选择器永远不会返回任何东

我建议拉值 id属性这是在匿名函数可用。

也许是这样的:

var idx = this.id.substring(6); // You may want something fancier here 
$('#app_dates' + idx).hide(); 

当我做你的jsfiddle这种变化,我可以得到第一个消失。