我想要实现的目标:
我的表单由#item
,#unit
,#price
和#total
四个字段组成。
用户可以输入多行#item
和#unit
。为此,如果用户点击“添加新行”,则会出现一个新行以接收项目和单位(数量)的用户输入。如果用户在现有行上单击“ - ”,则该行将为除去。
使用javascript change()
实时识别选择的项目。
使用ajax动态检索所选项目的价格,并将价格数据附加到#price
元素中,并通过计算#total
填充#unit x #price
元素。
为实现这一目标,这就是我所做的。
首先,我的 HTML表单如下所示。
<form id="form">
<input type="submit" name="create" value="Create" />
<!-- dynamically add more lines -->
<div class="form-group table-row hide" id="template">
<!-- remove button-->
<div class="table-cell" style="width: 45px;">
<a class="btn btn-default removeButton">
<span class="glyphicon glyphicon-minus">
</span>
</a>
</div>
<!-- user input: item -->
<div class="table-cell">
<select id="item" class="form-control">
<option value=""></option>
<option value="item-1">Item 1</option>
<option value="item-2">Item 2</option>
<option value="item-3">Item 3</option>
</select>
</div>
<!-- user input: quantity -->
<div class="table-cell">
<input id="unit" min="1" step="1" value="1" type="number" class="form-control" />
</div>
<!-- price is dynamically filled up using ajax -->
<div class="table-cell">
<input id="price" type="text" class="form-control" />
</div>
<!-- total is dynamically calculated -->
<div class="table-cell">
<input id="total" type="text" class="form-control" />
</div>
</div>
<button type="button" class="btn btn-default addButton">Add new line</button>
</form>
javascript代码实现动态添加/删除输入表单。
<script>
jQuery(document).ready(function($) {
var idx = new Number( 0 );
$('#form')
// Add button click handler
.on('click', '.addButton', function() {
var $template = $('#template'),
$clone = $template
.clone()
.removeClass('hide')
.removeAttr('id')
.insertBefore($template);
// assign name attributes with proper array name and index
$clone.find('#item').attr('name', 'lines[' + idx + '][item]').attr('required', 'required').val('');
$clone.find('#unit').attr('name', 'lines[' + idx + '][unit]').attr('required', 'required').val('');
$clone.find('#price').attr('name', 'lines[' + idx + '][price]').attr('required', 'required').val('');
$clone.find('#total').attr('name', 'lines[' + idx + '][total]').val('');
idx = idx + 1;
})
// Remove button click handler
.on('click', '.removeButton', function() {
if (confirm("<?php _e( 'Are you sure you wish to remove this line? This cannot be undone.', 'doumi' ); ?>")) {
var $row = $(this).parents('.form-group');
// Remove element containing the option
$row.remove();
idx = idx - 1;
}
});
});
</script>
最后, jQuery调用ajax 。
<script>
/* Get Item Price */
jQuery('#item').change(function(){
var $item_id=$('#item').val();
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
// call ajax
jQuery("#price").empty();
jQuery.ajax({
url: ajaxurl,
/* ******************************************************************** */
/* ajax_get_item_price is a function that returns the price of the item */
/* ******************************************************************** */
data:' action=ajax_get_item_price&item_id='+$item_id,
type:'GET',
success:function(results) {
jQuery("#price").append(results);
}
});
});
</script>
我可以动态添加和删除输入表单的行。
问题是每行中的表单元素的名称如下所示;
<select id="item" name="lines[0][item]"></select>
<input id="unit" name="lines[0][unit]" />
<input id="price" name="lines[0][price]" />
<input id="total" name="lines[0][total]" />
<select id="item" name="lines[1][item]"></select>
<input id="unit" name="lines[1][unit]" />
<input id="price" name="lines[1][price]" />
<input id="total" name="lines[1][total]" />
<select id="item" name="lines[2][item]"></select>
<input id="unit" name="lines[2][unit]" />
<input id="price" name="lines[2][price]" />
<input id="total" name="lines[2][total]" />
...
...
...
<select id="item" name="lines[n][item]"></select>
<input id="unit" name="lines[n][unit]" />
<input id="price" name="lines[n][price]" />
<input id="total" name="lines[n][total]" />
我想因为有多个#item
具有不同的名称,所以jQuery不知道它需要注意哪个#item
。但是,我也不知道如何使用相关的#item正确调用ajax。
非常感谢任何建议。
答案 0 :(得分:1)
好吧,正如我所说,id对于页面应该是唯一的,所以对于类似的项目,你应该使用类:
....
<select class="item" name="lines[2][item]"></select>
<input class="unit" name="lines[2][unit]" />
<input class="price" name="lines[2][price]" />
<input class="total" name="lines[2][total]" />
....
因此,对于change
事件,请使用类似
jQuery('.item').change(function(){
// to narrow the items, use this
var this$ = $( this );
// this$ contain exactly one item, which is currently changing
// do stuff
});
不知道究竟发生了什么错误,但我认为你的price
项目太多了,因而发布了问题。
因此,下一行将执行此操作:获取所有#price
元素,并将结果附加到每个元素。
success:function(results) {
jQuery("#price").append(results);
}
您应该澄清您确切需要哪个#price
项目。
首先,正如我已经提到的 - 使用多个类似字段的类jQuery(".price")
其次,添加一些说明确切应该更新的字段。
可以有很多方法,我展示两个
单向,使用next
功能。
success:function(results) {
this$.next('.price').eq(0).append(results);
// here we refer to this$ - we try to find all `.price` element
// which come after our `select`
// as there can be a lot of them we take only the first one
}
另一种方式,在元素分组的边界中使用context
种类,即一些div。
我建议像这样更改你的HTML
<div class="item-wrapper">
<select class="item" name="lines[2][item]"></select>
<input class="unit" name="lines[2][unit]" />
<input class="price" name="lines[2][price]" />
<input class="total" name="lines[2][total]" />
</div>
因此,你的字段的每个块都将包含在div中。
之后,我们可以告诉jQUery仅在已更改.price
所在的div中找到select
元素
success:function(results) {
var parent$ = this$.parent();
// again we refer to this$ getting its parent which is div
parent$.find('.price').append(results);
// here we try to find `.price` element located in a parent$ div.
// As it is definitely only one, we don't need to use any other code.
}
所以,这就是我能说的全部)