我不知道如何跟踪更改并将更改传递给具有相同 ID 的按钮。有一个设置模块,它显示产品卡片中的产品。
如果我在一个产品中选择了一个选项(输入),则该选项的数据将传输到按钮并退出(大小:M)但如果有两个具有相同 ID 的按钮,则数据将仅传输到一个(我写信给作者,但他说这是不可能的,因为数据只能通过唯一ID传输......
总的来说,我对这个JS有点了解,但对我来说有点复杂......
我们监听输入,如果有变化,我们执行 kjset.initEvent();
$(document).ready(function() {
kjset.initEvent();
startTimer();
setTimeout(function() { $(".set-options input").trigger('change'); } , 500);});
在这部分有一段代码将数据传递给按钮
var kjset = {
product_id: null,
iset: null,
gproducts: [],
set_modal: false,
current_set: null,
initEvent: function() {
var obj = this;
$(".add-set-btn").click(function() {
$(this).button('loading');
$(this).parents('.sets-owl').trigger('autoplay.stop.owl');
product_id = $(this).parents('.set').find("input[name='sp_product_id']").val();
iset = $(this).parents('.set').find("input[name='sp_iset']").val();
gproducts = $(this).parents('.set').find('.set-product').filter(function(index) {
return $(this).find("input[name='sp_include']").is(":checked");
});
products = $(this).parents('.set').find('.set-product').filter(function(index) {
return $(this).find("input[name='sp_include']").is(":checked");
});
obj.current_set = $(this).parents('.set');
obj.recuesiveCheckSetOptions(products);
$(".sets-owl").trigger("owl.stop");
});
$("input[name='sp_set_quantity']").change(function() {
obj.current_set = $(this).parents('.set');
obj.update_total();
});
$(".set input[name='sp_include']").change(function() {
obj.current_set = $(this).parents('.set');
obj.update_total();
});
$(".set-options").remove().appendTo('body');
$('.apply-options').on('click', function() {
var btn_id = $(this).parents('.modal').attr('id');
$('button[data-target="#' + btn_id + '"]').parents('.set').find('.add-set-btn').first().trigger("click");
});
$(".set-options select,.set-options input[type='radio'],.set-options input[type='checkbox']").change(function() {
var options = $(this).parents('.set-options').find("select option:selected,input[type='radio']:checked,input[type='checkbox']:checked");
var btn_id = $(this).parents('.set-options').attr("id");
var product = $("button[data-target='#" + btn_id + "'").parents('.set-product');
obj.current_set = $(product).parents('.set');
var cprice = parseFloat($(product).find("input[name='sp_cprice']").val());
var eq_mod = false;
var total = cprice;
var str_opts = "";
$(options).each(function() {
//console.log($(this).parents('.form-group').find('label'));
str_opts += $(this).parents('.form-group').find('label').eq(0).text().trim();
str_opts += ": ";
str_opts += $(this).parent('label').text().trim();
str_opts += "<br/>";
// console.log(str_opts);
var pre = $(this).data('prefix');
var price = parseFloat($(this).data('price'));
if (pre.length != 0 && isNaN(price) == false) {
switch (pre) {
case '-':
total -= price;
break;
case '+':
total += price;
break;
case '=':
total = price;
break;
case '*':
total *= price;
break;
case '/':
total /= price;
break;
case 'u':
total = total + (($total * price) / 100);
break;
case 'd':
total = total - ((total * price) / 100);
break;
default:
break;
}
}
});
$("button[data-target='#" + btn_id + "'").html(str_opts);
//console.log(str_opts);
total -= cprice;
$(product).find("input[name='sp_option_price']").val(total);
obj.update_total();
});
},
initCarousel: function() {
kjsetInitCarousel(".sets-owl");
},
numberWithSpaces: function(number) {
//return number;
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
},
roundNumber: function(number) {
decimals = parseInt(getDecimal());
var dec = Math.pow(10, decimals)
var part1, part2;
var nnumber;
if (decimals) {
nnumber = "" + Math.round(parseFloat(number) * dec + .0000000000001);
if (number > 1) part1 = nnumber.slice(0, -1 * decimals);
else part1 = "0";
part2 = nnumber.slice(-1 * decimals);
return this.numberWithSpaces(part1) + "." + part2;
} else return this.numberWithSpaces(Math.round(number));
},
animateCounter: function(selector, oldp, newp) {
var obj = this;
if (oldp !== newp) $(selector).prop('Counter', oldp).animate({
Counter: newp
}, {
duration: 500,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
},
complete: function() {
$(selector).html(obj.roundNumber(newp));
}
});
},
update_total: function() {
var obj = this;
var set = obj.current_set;
var cprice;
var option_price;
var qty;
var qqty;
var actual_price;
var total = 0;
var start;
var total_economy = 0;
var economy;
var qs = parseInt($(set).find("input[name='sp_set_quantity']").val());
if (set.length > 1) set = $(set).last();
$(set).find('.set-product').each(function(index) {
if ($(this).find("input[name='sp_include']").length)
if ($(this).find("input[name='sp_include']").is(':checked') == false) return;
qqty = qty = parseInt($(this).find("input[name='sp_quantity']").val());
qty *= qs;
if ($(this).find('input[name="sp_discounts_json"]').length) {
var discounts = JSON.parse($(this).find('input[name="sp_discounts_json"]').val());
$.each(discounts, function(index, value) {
if (qty >= parseInt(index)) cprice = value;
});
} else cprice = parseFloat($(this).find("input[name='sp_cprice']").val());
if($(this).find('input[name="sp_discount_from"]').val()=='old')
cprice_for_disc = parseFloat($(this).find("input[name='sp_oldcprice']").val());
else
cprice_for_disc=cprice;
option_price = parseFloat($(this).find("input[name='sp_option_price']").val());
discount = $(this).find("input[name='sp_discount']").val();
cprice += option_price;
cprice_for_disc += option_price;
if (discount.substring(discount.length - 1) == "%")
economy = (cprice_for_disc / 100) * parseFloat(discount.slice(0, -1));
else
economy = discount / qqty;
total_economy += economy * qty;
total += (cprice * qty);
cprice = (cprice-economy)*qty;
start = parseFloat(($(this).find('.new_price .num').html()).replace(/\s/g, ''));
obj.animateCounter($(this).find(".new_price .num"), start, cprice);
});
total_economy = getRoundEconomy(total_economy);
total -= total_economy;
if ($(set).find('.set-total .economy').length) {
start = parseFloat(($(set).find('.set-total .economy .economy_val .num').html()).replace(/\s/g, ''));
obj.animateCounter($(set).find('.set-total .economy .economy_val .num'), start, total_economy);
if (total_economy != 0) $(set).find('.set-total .economy').fadeTo("slow", 1);
else $(set).find('.set-total .economy').fadeTo("slow", 0);
}
start = parseFloat(($(set).find('.set-total .new_summ .num').html()).replace(/\s/g, ''));
obj.animateCounter($(set).find('.set-total .new_summ .num'), start, total);
},
addSetToCart: function() {
var products = {};
var jsons = [];
var obj = this;
var qs = parseInt($(obj.current_set).find("input[name='sp_set_quantity']").val());
var newproducts={};
var lastprod;
$.each(gproducts, function(key, value) {
var options = obj.getOptions(value);
var product_id = $(value).find('input[name="sp_product_id"]').val();
var quantity = $(value).find('input[name="sp_quantity"]').val();
var post_products = {};
post_products.product_id = product_id;
post_products.quantity = quantity*qs;
post_products.option=$(options).filter('*[name^="sp_option["]').serialize();
newproducts[key]=post_products;
});
$.ajax({
url: 'index.php?route=extension/module/sets/addSetToCart',
type: 'post',
async: false,
data: {products:newproducts},
dataType: 'json',
success: function(json) {
$('.alert-dismissible, .text-danger').remove();
$('.form-group').removeClass('has-error');
if (json['error']) {
if (json['error']['option']) {
let errorOption = '';
for (i in json['error']['option']) {
var element = $('#input-option' + i.replace('_', '-'));
if (element.parent().hasClass('input-group')) {
element.parent().after('<div class="text-danger"><span class="KT-danger"><i class="fas fa-exclamation"></i>' + json['error']['option'][i] + '</span></div>');
} else {
element.after('<div class="text-danger"><span class="KT-danger"><i class="fas fa-exclamation"></i>' + json['error']['option'][i] + '</span></div>');
}
errorOption += '<div class="alert-text-item">' + json['error']['option'][i] + '</div>';
}
usNotify('danger', errorOption);
}
if (json['error']['error_warning']) {
usNotify('danger', json['error']['error_warning']);
}
if (json['error']['recurring']) {
$('select[name=\'recurring_id\']').after('<div class="text-danger"><span class="KT-danger"><i class="fas fa-exclamation"></i>' + json['error']['recurring'] + '</span></div>');
}
// Highlight any found errors
$('.text-danger').parent().addClass('has-error');
var scrollTo = $( ".has-error .text-danger" ).first();
$('html, body').animate({scrollTop: scrollTo.offset().top - 350})
}
if (json['success']) {
usNotify('success', json['success']);
octPopupCart();
if(typeof octYandexEcommerce == 'function') {
octYandexEcommerce(json);
}
// Need to set timeout otherwise it wont update the total
setTimeout(function () {
$('#oct-cart-quantity, .header-cart-index, .mobile-header-index').html(json['total_products']);
$('.us-cart-text').html(json['total_amount']);
}, 100);
}
}
});
},
addSetToCartSuccess: function(json) {
kjsetAddSetToCartSuccess(json);
},
clearOptionPrice: function() {
$("input[name='sp_option_price']").val(0);
},
addSetToTotal: function() {
var obj = this;
$.ajax({
url: 'index.php?route=extension/module/sets/addSetToTotal',
type: 'post',
data: {
sp_product_id: product_id,
sp_iset: iset
},
dataType: 'json',
success: function() {
obj.addSetToCart(iset);
}
});
},
getOptions: function(product) {
var modal_selector = $($(product).find('.open-options').data('target'));
var options = $(product).find('input[type="hidden"],input[type="checkbox"]');
if (modal_selector.length) {
var options_modal = $(modal_selector).find('input[type=\'text\'], input[type=\'hidden\'], input[type=\'date\'], input[type=\'time\'], input[type=\'datetime\'], input[type=\'radio\']:checked, input[type=\'checkbox\']:checked, select, textarea');
var options = $.merge(options_modal, options);
}
return options;
},
recuesiveCheckSetOptions: function(products) {
var obj = this;
var product = products.shift();
var options = obj.getOptions(product);
var modal_selector = $($(product).find('.open-options').data('target'));
$.ajax({
url: 'index.php?route=extension/module/sets/checkProductOption',
type: 'post',
data: options,
dataType: 'json',
success: function(json) {
$(modal_selector).find('.text-danger').parent().removeClass('has-error');
$(modal_selector).find('.text-danger').remove();
if (json['error']) {
var btn = $(obj.current_set).find(".add-set-btn");
$(btn).button('reset');
if (json['error']['option']) {
$(".modal").modal('hide');
if (modal_selector.length) setTimeout(function() {
$(modal_selector).modal('show')
}, 500);
for (i in json['error']['option']) {
var element = $(modal_selector).find('#set-input-option' + i.replace('_', '-'));
if (element.parent().hasClass('input-group')) {
element.parent().after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
} else {
element.after('<div class="text-danger">' + json['error']['option'][i] + '</div>');
}
}
}
if (modal_selector.length) $(modal_selector).find('.text-danger').parent().addClass('has-error');
} else if (json['success']) {
if (products.length > 0) obj.recuesiveCheckSetOptions(products);
else {
$(".modal").modal('hide');
obj.addSetToTotal();
}
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
}};
这是执行并将数据传递给按钮的代码
$("button[data-target='#" + btn_id + "'").html(str_opts);
树枝中的按钮本身
{% if (options) %}<div class="dm-com-vd-button-1"><button type="button" class="btn btn-primary open-options" data-toggle="modal" data-target="#sets-popup-{{ modal_id }}">{{ text_sets_options }}</button></div>{% endif %}
问题是按钮有一个数据目标,它的 ID 是你已经看到的。而事实是,如果有两个按钮具有相同的 ID,那么带有 str_opts 的数据只替换在一个按钮中。而且我不知道如何让str_opts数据插入到所有具有相同ID的按钮中,即使我找到一个例子,我也不明白我找到了什么......
完整脚本