1

I need some help understanding why bootstrap popover works in such a weird way. I am dynamically creating a list of buttons in bootstrap popover from a predefined list of persons in a JSON file. The behavior is fine when the first two persons are added, but from the third person, the list of buttons screws up, i.e. adding more persons into the list than the code dictates. Does anyone know why that is?

In the below demo/fiddle, the logic works as such: as persons are being added, we take out those who have been added previously. The same person should not be added twice.

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'>&#8870;</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'>&#8870;</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;
}

My fiddle: http://jsfiddle.net/s3vrew37/

revvy
  • 151
  • 3
  • 16

0 Answers0