在 AJAX 表单提交中使用 jquery 数据选择器识别哪个类发出请求



我有一系列组,每个组都包含项目列表。我已经在数量字段中添加了递减/递增按钮,并希望它通过 AJAX 工作。

其中一个输入字段的示例 html 是

<div class="ContentCell list_product_qty_wrapper nbr nbt">
<input type="text" name="cartlist_quantity" value="1" size="4" class="cart_input_1881" />
<input type="hidden" name="products_id" value="1881" />
<input type="hidden" name="cartlist_group_id" value="1" />
</div>

将递增/递减按钮添加到输入字段并启动 AJAX 调用的完整脚本是

// Add Increment/Decrement buttons
function add_quantity_buttons(element, vertical) {
quantity_input = jQuery(element);
quantity_input.attr('min', '0').attr('inputmode', 'numeric').attr('pattern', '[0-9]*').addClass('inc_dec_quantity_field').wrap('<div class="quantity_field_wrapper clearfix"></div>');
if (jQuery('.device-xs').is(':visible')) {
quantity_input.attr('type', 'number');
} else {
quantity_input.attr('type', 'text');
}
quantity_input.before('<a href="#decrease_quantity" class="quantity_dec_button">-</a>').after('<a href = "#increase_quantity" class = "quantity_inc_button" > + </a>');
}
// Handle quantity buttons
// Increment/Decrement button functionality
function increment_decrement_quantity(element, value) {
$(document.body).on('click', element, function(e) {
e.preventDefault();
quantity = $(this).parent().find(('input'));
quantity_value = parseInt(quantity.val(), 10);
quantity_multiple = undefined;
if (quantity.data('multiple') !== undefined && (quantity.data('multiple') > 0 || quantity.data('multiple') < 0)) {
quantity_multiple = parseInt(quantity.data('multiple'), 10);
if (value < 0) {
quantity_multiple = quantity_multiple * -1;
}
}
if (quantity_multiple !== undefined && (quantity_multiple > 0 || quantity_multiple < 0)) {
quantity_value = Math.floor(quantity_value / quantity_multiple) * quantity_multiple;
value = quantity_multiple;
} else {
value = parseInt(value, 10);
}
// Validate quantity and increment/decrement value
if (value > 0 || value < 0 && quantity_value > 0) {
quantity.val(quantity_value + value).trigger('change');
}
});
}
// Remove number type and add quantity change buttons
add_quantity_buttons('#listContentsDisplay input[name^="cartlist_quantity"]', true);
// Decrement button
increment_decrement_quantity('.quantity_dec_button', -1);
// Increment button
increment_decrement_quantity('.quantity_inc_button', +1);
// Quantity input validation
var ajax_called = false;
$(document.body).on('propertychange change click keyup input paste blur', '.inc_dec_quantity_field', function(e) {
character_code = !e.charCode ? e.which : e.charCode;
quantity_value = $(this).val();
leading_zero_plus_regexp = /^(0[0-9]|+[+,0-9]).*$/;
// When input goes out of focus validate quantity value
if (e.type == 'blur' && (quantity_value == '' || isNaN(quantity_value / 1) == true || isNaN(quantity_value / 1) == false && quantity_value <= 0)) {
$(this).val('0');
} else {
// Check for numeric value and allow backspace, delete, left and right arrows
if ((isNaN(quantity_value / 1) == false && quantity_value > 0) || (character_code != undefined && (character_code == 39 || character_code == 37 || character_code == 8 || character_code == 46))) {
// Correct value
// Make sure the quantity is integer
if (quantity_value != '' && isNaN(quantity_value / 1) == false && (quantity_value != parseInt(quantity_value, 10) || leading_zero_plus_regexp.test(quantity_value))) {
$(this).val(parseInt(quantity_value, 10));
}
} else if (character_code != undefined) {
// Incorrect value
$(this).val('0');
} else if (quantity_value != '' && isNaN(quantity_value / 1) == false && (quantity_value != parseInt(quantity_value, 10) || leading_zero_plus_regexp.test(quantity_value))) {
// Make sure the quantity is integer
$(this).val(parseInt(quantity_value, 10));
}
}
// AJAX update quantity
//if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper') && !ajax_called) {
//if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper[data-groupid="' + jQuery(this).data("groupid") + '"]') && !ajax_called) {
// if (e.type != 'click' && $(e.target).parent().parent().data('groupid') == jQuery(this).data("groupid") && !ajax_called) { changed to this after suggestion from Ivan (SO)
if (e.type != 'click' && $(e.target).data('groupid') == jQuery(this).data("groupid") && !ajax_called) { // Ivan (SO) suggestion didn't give an 'OK' in console log. Removing .parent().parent(), it does give an ok, but still only submits the last group to AJAX update 
console.log('OK');
call_delay(function() {
var form = $('form[name="cartlist"]');
ajax_called = true;
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize()
}).success(function(data) {
if ($('#cartlistDefault').length && $(data).find('#cartlistDefault').length) {
$('#cartlistDefault').replaceWith($(data).find('#cartlistDefault'));
// Remove number type and add quantity change buttons
add_quantity_buttons('#listContentsDisplay input[name^="cartlist_quantity"]', true);
// Replace classes missing after AJAX callback
$('select').addClass('select_caret_icon form-control');
if ($('input[type="submit"].cssButton').length > 0) {
$('input[type="submit"].cssButton').attr("data-btn", "btn btn-md");
}
}
ajax_called = false;
}).fail(function(data) {
ajax_called = false;
});
}, 300);
}
});    

我的问题是增量仅适用于while循环中生成的最后一个组。

根据我昨天提出的一个问题(多个复选框以触发 js 脚本(,我在识别请求来自哪个组时遇到了类似的问题,我在这里尝试了相同的方法,

取代

<div class="ContentCell list_product_qty_wrapper nbr nbt">

<div class="ContentCell list_product_qty_wrapper nbr nbt" data-groupid="1">

并在脚本中,替换

if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper') && !ajax_called) {

if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper[data-groupid="' + jQuery(this).data("groupid") + '"]') && !ajax_called) {

但是,执行此操作后,没有任何增量按钮会触发 AJAX 进程。

此小提琴 https://jsfiddle.net/8h4gzmu3/显示输入字段和递增/递减的外观,并且按钮在单击时确实会更新数量,但一旦 AJAX 调用完成,第一个和第二个输入就不会更新。只有最后一个是。

显然,我还没有完全掌握使用数据选择器的概念。

我哪里做错了?

因为您使用的是 hasClass 查看类而不是属性,并且在 html 中您将数据组 ID 添加为属性

您可以尝试如果父数据组ID与此相同,则应该可以工作

if (e.type != 'click' && $(e.target).parent().parent().data('groupid') == jQuery(this).data("groupid") && !ajax_called) {

更新

您可以按照此逻辑进行操作,为按钮和当前输入添加相同的组ID,然后在if语句中将它们相互匹配。

这是匹配当前输入的示例,如果更改与按钮组ID不同的输入组ID,则语句将为FALSE,并且不会获得控制台日志

// Add Increment/Decrement buttons
function add_quantity_buttons(element, vertical) {
quantity_input = jQuery(element);
quantity_input.attr('min', '0').attr('inputmode', 'numeric').attr('pattern', '[0-9]*').addClass('inc_dec_quantity_field').wrap('<div class="quantity_field_wrapper clearfix"></div>');
if (jQuery('.device-xs').is(':visible')) {
quantity_input.attr('type', 'number');
} else {
quantity_input.attr('type', 'text');
}
quantity_input.before('<a href="#decrease_quantity" data-group-id="1" class="quantity_dec_button">-</a>').after('<a href = "#increase_quantity" data-groupid="1" class = "quantity_inc_button" > + </a>');
}
// Handle quantity buttons
// Increment/Decrement button functionality
function increment_decrement_quantity(element, value) {
$(document.body).on('click', element, function(e) {
e.preventDefault();
quantity = $(this).parent().find(('input'));
quantity_value = parseInt(quantity.val(), 10);
quantity_multiple = undefined;
if (quantity.data('multiple') !== undefined && (quantity.data('multiple') > 0 || quantity.data('multiple') < 0)) {
quantity_multiple = parseInt(quantity.data('multiple'), 10);
if (value < 0) {
quantity_multiple = quantity_multiple * -1;
}
}
if (quantity_multiple !== undefined && (quantity_multiple > 0 || quantity_multiple < 0)) {
quantity_value = Math.floor(quantity_value / quantity_multiple) * quantity_multiple;
value = quantity_multiple;
} else {
value = parseInt(value, 10);
}
// Validate quantity and increment/decrement value
if (value > 0 || value < 0 && quantity_value > 0) {
quantity.val(quantity_value + value).trigger('change');
}
});
}
// Remove number type and add quantity change buttons
add_quantity_buttons('.ContentCell input[name^="cartlist_quantity"]', true);
// Decrement button
increment_decrement_quantity('.quantity_dec_button', -1);
// Increment button
increment_decrement_quantity('.quantity_inc_button', +1);
// Quantity input validation
var ajax_called = false;
$(document.body).on('propertychange change click keyup input paste blur', '.inc_dec_quantity_field', function(e) {
character_code = !e.charCode ? e.which : e.charCode;
quantity_value = $(this).val();
leading_zero_plus_regexp = /^(0[0-9]|+[+,0-9]).*$/;
// When input goes out of focus validate quantity value
if (e.type == 'blur' && (quantity_value == '' || isNaN(quantity_value / 1) == true || isNaN(quantity_value / 1) == false && quantity_value <= 0)) {
$(this).val('0');
} else {
// Check for numeric value and allow backspace, delete, left and right arrows
if ((isNaN(quantity_value / 1) == false && quantity_value > 0) || (character_code != undefined && (character_code == 39 || character_code == 37 || character_code == 8 || character_code == 46))) {
// Correct value
// Make sure the quantity is integer
if (quantity_value != '' && isNaN(quantity_value / 1) == false && (quantity_value != parseInt(quantity_value, 10) || leading_zero_plus_regexp.test(quantity_value))) {
$(this).val(parseInt(quantity_value, 10));
}
} else if (character_code != undefined) {
// Incorrect value
$(this).val('0');
} else if (quantity_value != '' && isNaN(quantity_value / 1) == false && (quantity_value != parseInt(quantity_value, 10) || leading_zero_plus_regexp.test(quantity_value))) {
// Make sure the quantity is integer
$(this).val(parseInt(quantity_value, 10));
}
}
// AJAX update quantity
//if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper') && !ajax_called) {
//if (e.type != 'click' && $(e.target).parent().parent().hasClass('list_product_qty_wrapper[data-groupid="' + jQuery(this).data("groupid") + '"]') && !ajax_called) {
// if (e.type != 'click' && $(e.target).parent().parent().data('groupid') == jQuery(this).data("groupid") && !ajax_called) { changed to this after suggestion from Ivan (SO)
if (e.type != 'click' && $('.quantity_inc_button').data("groupid") == $(e.target).data('groupid') && !ajax_called) { // Ivan (SO) suggestion didn't give an 'OK' in console log. Removing .parent().parent(), it does give an ok, but still only submits the last group to AJAX update 
console.log('input groupid: ' + $(e.target).data('groupid'));
console.log('button groupid: ' + $('.quantity_inc_button').data("groupid"));
console.log('OK')
// call_delay(function() {
//   var form = $('form[name="cartlist"]');
//   ajax_called = true;
//   $.ajax({
//     type: form.attr('method'),
//     url: form.attr('action'),
//     data: form.serialize()
//   }).success(function(data) {
//   if ($('#cartlistDefault').length && $(data).find('#cartlistDefault').length) {
//    $('#cartlistDefault').replaceWith($(data).find('#cartlistDefault'));
// Remove number type and add quantity change buttons
//      add_quantity_buttons('#listContentsDisplay input[name^="cartlist_quantity"]', true);
// Replace classes missing after AJAX callback
//      $('select').addClass('select_caret_icon form-control');
//      if ($('input[type="submit"].cssButton').length > 0) {
//        $('input[type="submit"].cssButton').attr("data-btn", "btn btn-md");
//      }
//    }
//    ajax_called = false;
//   }).fail(function(data) {
//     ajax_called = false;
//   });
// }, 300);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ContentCell list_product_qty_wrapper nbr nbt">
<input type="text" name="cartlist_quantity" data-groupid="1" value="1" size="4" class="cart_input_1881" />
<input type="hidden" name="products_id" value="1881" />
<input type="hidden" name="cartlist_group_id" value="1" />
</div>

最新更新