1

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

网页:

  1. 首先要求用户选择应用程序的数量
  2. 根据用户的选择,为每个申请生成两个输入字段“申请时间”和“申请日期”。
  3. “申请时间”中有两个选项。如果用户选择“默认”,“申请日期”将消失。

问题:当超过三个应用程序时,只有最后一个“应用程序日期”会消失,无论在哪里进行选择。我认为这是因为我没有使用正确的选择器。

演示

代码

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

            })
        }
    })


})​
4

4 回答 4

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

上面的行在处理程序内,change直到处理程序触发才执行。在它触发时,这将获得最后一个元素,这会导致您观察到的行为。您可以使用以下内容:

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

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

编辑:

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

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

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

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

于 2012-09-10T21:13:49.370 回答
3

代替

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

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

:last或使用i不会工作,因为事件将在整个 for 循环被迭代之后发生。

于 2012-09-10T21:11:18.590 回答
2

尝试:

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

jsFiddle 示例

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

于 2012-09-10T21:13:20.033 回答
0

当您的函数被调用时,它会尝试访问变量i ,该变量 i已递增到比您在顶部下拉菜单中选择的数字多 1 ,因此您不能使用它。你的选择器永远不会返回任何东西。

我建议将i的值从匿名函数中可用的this的 id 属性中提取出来。

也许是这样的:

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

当我在您的 jsFiddle 中进行更改时,我可以让第一个消失。

于 2012-09-10T21:22:18.747 回答