希望我的最后一个问题,虽然我不能确定......
我正在尝试生成一个表单,一旦输入数据,它就会创建一个用于输入数据的新区域。这似乎是一个非常微不足道的问题,我可以想到这样一种形式的几种可能用途(在应用程序上输入作业历史记录,输入可以联系到的电话号码列表等)。
输入数据后很容易创建一个新行,但是我找不到告诉这个新行的方法,当数据输入它时,它应该创建另一行
为了简单起见,为了帮助获得我想要的外观,我正在为表单使用表格,每次输入任何内容到最后一行时,它都会创建一个新行。这是我正在使用的HTML:
<table>
<tr>
<th>Field 1</th>
<th>Field 2</th>
<th>Field 3</th>
</tr>
<tr>
<input type="hidden" name="id-row-0" value="0" />
<td><input type="text" name="field1-row-0" value="" /></td>
<td><input type="text" name="field2-row-0" value="" class="date-field" /></td>
<td><input type="text" name="field3-row-0" value="" /></td>
</tr>
</table>
然后我有以下javascript:
$.spreadsheet = {
fields : $('#myForm').find('input,textarea,select'), // list of input HTML elements
rows : $('#myForm').find('tr').length - 1, // number of rows currently. Subtract 1 for table headers
columns : $('#myForm').find('tr')[0].cells.length // number of fields pulled from the database
}
$($.spreadsheet.fields).find('input,textarea,select').change( function() {
var index = $.spreadsheet.fields.index( $( this ) );
var row = Math.floor(index / $.spreadsheet.columns);
if( row == $.spreadsheet.rows - 1 ) {
// Last row was changed. Do we add a new row?
if( $(this).val() != '' ) {
// A value was added. We ned a new row
new_row = $("input[name=id-row-"+row+"]").parent().clone().appendTo("#myForm table");
// Now we need to change the name of every element in this row to reflect the new row number
new_row.find('input,textarea,select').each( function() {
partial_name = this.name.substring(0, this.name.indexOf('-row-'+row));
this.name = partial_name + '-row-' + (row+1);
// If it was a datepicker before then the id will cause all sorts of issues
this.id = '';
$(this).removeClass('hasDatepicker');
});
// Create date pickers
new_row.find('.date-field').datepicker({ dateFormat: "yy-mm-dd", changeMonth: true, changeYear: true });
// Recursively set this function for change()?
// Help, guys =(
// Update the total number of rows
$.spreadsheet.rows += 1;
}
}
});
// Create date pickers
$( ".date-field" ).datepicker({ dateFormat: "yy-mm-dd", changeMonth: true, changeYear: true });
如您所见,我不确定如何递归设置此函数作为.change()
的回调。我尝试过做类似以下的事情:
function add_new_row = function() {
...
// Recursively set this function for change()?
new_row.find('input,textarea,select').change( add_new_row );
...
}
$($.spreadsheet.fields).find('input,textarea,select').change( add_new_row );
但它没有用。 javascript不支持任何形式的递归吗?如果没有,那么如何解决这个难题?
在@ J0HN的建议下使用.delegate()
后,这是我当前的javascript文件:
$(document).ready( function() {
$.spreadsheet = {
fields : $('#myForm').find('input,textarea,select'), // list of input HTML elements
rows : $('#myForm').find('tr').length - 1, // number of rows currently. Subtract 1 for table headers
columns : $('#myForm').find('tr')[0].cells.length, // number of fields pulled from the database
}
// Add new rows
$("#myForm").delegate("input, textarea, select", "change", function() {
var index = $.spreadsheet.fields.index( $( this ) );
var row = Math.floor(index / $.spreadsheet.columns);
var col = index % $.spreadsheet.columns;
if( row == $.spreadsheet.rows - 1 ) {
// Last row was changed. Do we add a new row?
if( $(this).val() != '' ) {
// A value was added. We ned a new row
// This row should look just like the previous... A CLONE, one might say?
new_row = $("input[name=id-row-"+row+"]").parent().clone().appendTo("#myForm table");
// Now we need to change the name of every element in this row to reflect the new row number
new_row.find('input, textarea, select').each( function() {
partial_name = this.name.substring(0, this.name.indexOf('-row-'+row));
this.name = partial_name + '-row-' + (row+1);
// We can't initialize a datepicker if it thinks one is already initialized
$(this).removeClass('hasDatepicker');
this.id = '';
});
// Create date pickers
new_row.find('.date-field').datepicker({ dateFormat: "yy-mm-dd", changeMonth: true, changeYear: true });
// Update the total number of rows
$.spreadsheet.rows += 1;
}
}
});
// Create date pickers
$( ".date-field" ).datepicker({ dateFormat: "yy-mm-dd", changeMonth: true, changeYear: true });
});
当我在第一行输入一些数据时,它会按预期成功添加一个新行。使用Chrome的“检查元素”功能,我可以检查这些新元素的行号,它们看起来都是正确的,日期选择器甚至可以正常工作。
然而,当我在这个新行中键入数据时,没有任何反应。没有添加任何行,没有错误,javascript不会崩溃(datepickers继续工作)......就好像永远不会调用“更改”方法一样。
想法?
答案 0 :(得分:4)
我认为jQuery.delegate
应该可以解决问题。它将事件处理程序“绑定”到现在或将来适合选择器的任何元素。
$("#myform").delegate("input, textarea, select", "change", function(){
//place row adding logic here
});