我需要一些帮助来理解为什么bootstrap popover以这种奇怪的方式工作。我正在从JSON文件中的预定义人员列表中动态创建引导弹出窗口中的按钮列表。添加前两个人时行为很好,但是从第三个人那里,按钮列表搞砸了,即在列表中添加的代码多于代码所指示的人数。有谁知道为什么会这样?
在下面的演示/小提琴中,逻辑工作如下:随着人们的加入,我们取出之前添加的人。同一个人不应该加两次。
HTML
<div class='col-md-12 d-none d-sm-none d-md-block'>
<div class='row my-2 div-add-group'>
<div class="col-md-auto text-center no-gutters">
<button class='btn btn-success btn-sm btn-add-group'><i class='fa fa-plus'></i> Add group</button>
</div>
</div>
</div>
<div style='display: none;'>
<div class='row my-2 group-button' data-group='A' id='grp-grp-fixed'>
<div class="col-md-1 text-center no-gutters">
<button class='btn btn-secondary btn-sm btn-grp'>Group A</button>
</div>
</div>
<div class='row my-2 signatory-button' id='grp-person-fixed'>
<div class="col-md-1 text-center no-gutters">
<span class='h4 align-middle'>⊦</span>
</div>
<div class="col-md-auto text-left no-gutters">
<button class='btn btn-success btn-sm btn-signatory-choose'>Select Signatory <i class='fa fa-chevron-down'></i></button>
</div>
</div>
<div class='row my-2 div-add-signatory' id='grp-person-add'>
<div class="col-md-1 text-center no-gutters">
<span class='h4 align-middle'>⊦</span>
</div>
<div class='col-md-auto text-right no-gutters'>
<span class='btn btn-success btn-sm btn-add-signatory'><i class='fa fa-user-plus'></i> Add signatory</span>
</div>
</div>
<div class='row my-2' id='grp-grp-add'>
<div class="col-md-auto text-center no-gutters">
<button class='btn btn-success btn-sm btn-add-group'><i class='fa fa-plus'></i> Add group</button>
</div>
</div>
<div id='cond-fixed'>
<div class='row my-2'>
<div class="col-md-1 text-left no-gutters">
<button class='btn btn-secondary btn-sm'><i class='fa fa-check'></i></button>
</div>
<div class="col-md-11 text-left no-gutters">
<div class='row'>
<div class="col-md-auto text-left no-gutters">
<p>Any</p>
</div>
<div class="col-md-auto text-left no-gutters">
<select class='form-control form-control-sm'>
<option>one</option>
</select>
</div>
<div class="col-md-auto text-left no-gutters">
<p>from Group</p>
</div>
<div class="col-md-auto text-left no-gutters">
<select class='form-control form-control-sm'>
<option>A</option>
</select>
</div>
<div class="col-md-auto text-left no-gutters">
<p>can sign for payments from amounts of up to</p>
</div>
</div>
<div class='row mb-2'>
<div class="col-md-auto text-left no-gutters">
<select class='form-control form-control-sm'>
<option>USD</option>
</select>
</div>
<div class="col-md-auto text-left no-gutters">
<input class='form-control form-control-sm' type='number' placeholder="1,000,000">
</div>
</div>
</div>
</div>
</div>
<div id='cond-add'>
<div class='row my-2'>
<div class="col-md-auto text-center no-gutters">
<button class='btn btn-danger btn-sm btn-add-group'><i class='fa fa-plus'></i> Add signing condition</button>
</div>
</div>
</div>
<div id='popover-signatories' class='hidden' style='display: none;'>
<div class="custom-controls-example col-xs-12 pl-0 popover-body-signatories" style="width: 250px;">
</div>
</div>
</div>
JS
var d = {
"connected-persons": {
"3753203948": {
"name": "Ben Lamb",
"D": false,
"C": false,
"B": true,
"A": false,
"P": false
},
"4512345412": {
"name": "Tom Green",
"D": true,
"C": false,
"B": false,
"A": true,
"P": true
},
"E5412345L": {
"name": "Ivey Lee",
"D": true,
"C": false,
"B": false,
"A": true,
"P": true
},
"S8501324A": {
"name": "Wilson Trump",
"D": false,
"C": false,
"B": false,
"A": true,
"P": false
},
"S7423144G": {
"name": "Leslie Brown",
"D": false,
"C": false,
"B": false,
"A": true,
"P": false
}
}
}
$(function() {
$(document).on('click', '.btn-add-signatory:not(.disabled)', function() {
var thisBtn = $(this);
$('#grp-person-fixed').clone().insertBefore(thisBtn.parents('.div-add-signatory'));
$('.btn-signatory-choose').popover({
trigger: 'click',
placement: 'bottom',
container: 'body',
html: true,
content: function() {
var output = "";
for (var id in d['connected-persons']) {
if (d['connected-persons'][id].A === true) {
if ($('div[id^="grp-person-fixed-"]').length) {
$('div[id^="grp-person-fixed-"]').each(function(k, v) {
if ($(v).attr('id').substring(17) != id) {
output = output + "<button class='btn btn-sm btn-success btn-block btn-add-signatory-person' data-id='" + id + "'>" + d['connected-persons'][id].name + "</button>";
}
});
} else {
output = output + "<button class='btn btn-sm btn-success btn-block btn-add-signatory-person' data-id='" + id + "'>" + d['connected-persons'][id].name + "</button>";
}
}
}
$('.popover-body-signatories').html(output);
return $('#popover-signatories').html();
}
}).on('shown.bs.popover', function() {
$('.btn-add-signatory-person').click(function() {
$('.popover-body-signatories').empty();
$('.btn-signatory-choose').popover('hide');
thisBtn.parent().parent().prev().find('.btn-signatory-choose').parent().html("<button class='btn btn-secondary btn-sm btn-signatory' data-id='" + $(this).data('id') + "'>" + $(this).text() + "</button>");
thisBtn.parent().parent().prev().attr('id', 'grp-person-fixed-' + $(this).data('id'));
thisBtn.removeClass('disabled');
});
});
thisBtn.addClass('disabled');
});
$('.btn-add-group').click(function() {
var grpLetter = 'A';
if ($('.div-add-group').prev().length == 0) {
$('#grp-grp-fixed').attr('data-group', grpLetter);
} else {
grpLetter = $('.div-add-group').prevAll('.group-button:first').data('group');
grpLetter = getNextKey(grpLetter);
$('#grp-grp-fixed').attr('data-group', grpLetter).find('button').text('Group ' + grpLetter);
}
$('#grp-grp-fixed').clone().insertBefore($('.div-add-group')).attr('id', 'grp-grp-fixed-' + grpLetter);
$('#grp-person-add').clone().insertBefore($('.div-add-group')).find('.btn-add-signatory').removeClass('disabled');
});
});
function getNextKey(key) {
if (key === 'Z' || key === 'z') {
return String.fromCharCode(key.charCodeAt() - 25) + String.fromCharCode(key.charCodeAt() - 25); // AA or aa
} else {
var lastChar = key.slice(-1);
var sub = key.slice(0, -1);
if (lastChar === 'Z' || lastChar === 'z') {
// If a string of length > 1 ends in Z/z,
// increment the string (excluding the last Z/z) recursively,
// and append A/a (depending on casing) to it
return getNextKey(sub) + String.fromCharCode(lastChar.charCodeAt() - 25);
} else {
// (take till last char) append with (increment last char)
return sub + String.fromCharCode(lastChar.charCodeAt() + 1);
}
}
return key;
}