我的目标:
相关代码:
我要填写的表格:
<table id='performer-payments' class='performer-profile payments-table'>
<tr>
<th> Period </th>
<th> Amount </th>
<th> Paid? </th>
</tr>
</table>
填充表格的代码:
for (period in data['Performers'][performer]['Payments']) {
var amount = utils.calcPerformerCut(data, performer, period);
var row = "<tr>";
row += "<td> " + period + " </td>";
row += "<td> " + amount + " $ </td>";
row += "<td>";
row += "<div class='performer-profile payment-status'>";
row += data['Performers'][performer]['Payments'][period];
row += "</div>";
row += "<select id='payment-status-" + performer + "-" + period + "' class='perfomer-profile hidden-onload displayNone payment-status-menu'>";
row += "<option value='paid'>Paid</option>";
row += "<option value='unpaid'>Unpaid</option>";
row += "<option value='transfer'>Transfer to...</option>";
row += "</select>";
row += "<select id='payment-transfer-period-" + performer + "-" + period + "' class='performer-profile hidden-onload displayNone payment-period-menu'>";
for (var i=0; i < data['Periods'].length; i++) {
row += "<option value='" + period + "'>" + period + '</option>';
}
row += "</select>";
row += "</td>";
row += "</tr>";
$('#performer-payments').append(row);
$('#performer-payments').on('change', {perf: performer, per: period}, function (even) {
if (even.target.value == 'transfer') {
utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), true);
} else {
utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), false);
}
});
}
供参考,切换可见性的代码:
exports.toggleVisible = function (selector, visible) {
if (visible) {
selector.removeClass('displayNone').addClass('displayBlock');
} else {
selector.removeClass('displayBlock').addClass('displayNone');
}
}
至少有两个问题:
注意:我欢迎对此提出反馈 - 我是一名经验丰富的程序员,但对HTML / JS / Jquery的经验很少。此外,我决定不使用模板进行这个项目,因为我正在尝试学习基础知识,所以如果你从看到我动态'添加行到表的方式得到胰腺炎,我道歉,但它是部分故意的。
除此之外,如果此处不清楚,请询问澄清。
编辑:以下是数据结构的相关部分:
data = {
'Performers': {
'Dira Klaggen': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Paid',
'Q3': 'Unpaid'
},
},
'Holden Bolden': {
'Payments': {
'Q2': 'Transferred to Q3',
'Q3': 'Unpaid'
}
},
'Manny Joe': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Unpaid',
'Q3': 'Unpaid',
}
}
},
'Periods': [
'Q1',
'Q2',
'Q3'
]
}
答案 0 :(得分:2)
您没有将change
处理程序附加到右侧元素。我应该是行中的第一个select
...而不是整个table
。
试试这个change
处理程序:
$('#performer-payments').find('#payment-status-' + performer + '-' + period).on('change', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
<小时/> 第二种方法:
id
的唯一select
。
假设您使用class
&#34;付款状态&#34;:
处理程序将是:
$('#performer-payments').on('change', '.payment-status', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
此处理程序可能不在行追加循环中,因为它使用delegation。
答案 1 :(得分:1)
通过执行以下操作来清理代码:
使用类而不是丑陋的ID。
使用data-attributes或隐藏的输入字段来保存额外信息。
使用event delegation绑定动态创建的元素。在事件处理程序内部,使用tree traversal方法根据当前元素this
限制搜索范围。
让我们应用这些东西。
像这样构建每一行。 {PLACEHOLDER}
是您在代码中放置变量内容的地方。
<tr>
<td>{PERIOD}</td>
<td>{AMOUNT} $ </td>
<td>
<div class='performer-profile payment-status'>
{SOMETHING-RELATING-TO-PERFORMER-PAYMENT-PERIOD}
</div>
<!-- remove ID -->
<!-- store performer and period in data-attributes -->
<select class='perfomer-profile hidden-onload displayNone payment-status-menu' data-performer='{PERFORMER}' data-period='{PERIOD}'>
<option value='paid'>Paid</option>
<option value='unpaid'>Unpaid</option>
<option value='transfer'>Transfer to...</option>
</select>
<!-- remove ID -->
<select class='performer-profile hidden-onload displayNone payment-period-menu'>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<!-- etc -->
</select>
</td>
</tr>
在JavaScript中,创建一个delegated event handler。请注意语法。
$(function () {
// ...
for (period in data['Performers'][performer]['Payments']) {
// build and append row
}
// create delegated event handler once and outside FOR loop
$(document).on('change', '.payment-status-menu', function () {
// get the current status menu
var statusMenu = $(this);
// find its related period menu
var periodMenu = statusMenu.closest('tr').find('.payment-period-menu');
// toggle its visibility
periodMenu.toggle(this.value == 'Transfer');
// of course, this could be a one-liner
//$(this).closest('tr').find('.payment-period-menu').toggle(this.value == 'Transfer');
});
});
您似乎不需要(2.)但如果您这样做,请在事件处理程序中使用statusMenu.data('performer')
or statusMenu.data('period')
来获取其执行者和期间值。您也可以this.dataset.performer
or this.dataset.period
。