Kennedy Voorhees Kennedy Voorhees - 2 months ago 47
jQuery Question

Clickable button within bootstrap list-group

I have a list-group with list-group-items in it in the form of buttons. I would like to add clickable icons to each list-group-item, for example delete buttons. However, when adding an icon to a list-group-item I can either prepend the icon to the list-group-item or place it before the item. When I prepend the icon, it comes out like this. Clicking the delete icon triggers the click event for the entire list-group-item, not the click event for the delete icon.

Javascript where I add the list-group-items and the delete icon(button):

var button = $('<button/>').text(result[key].deviceId).addClass('list-group-item device').attr({name:result[key].deviceId, "aria-label": "Quick View Device", "data-toggle": "modal", "data-target": "#quick-view-device-modal", type: "button"});
var deviceName = result[key].deviceId;
var deleteButton = $('<button/>').attr('type','button').attr('name','delete').attr('id',deviceName).html('<span class="glyphicon glyphicon-minus-sign red"></span>').addClass('icon delete-device');
button.prepend(deleteButton);
$('#device-list').append(button);


This code ends up adding the delete icon button within the list-group-item button, as a child element. I believe that is why clicking the delete icon button triggers the click event for the entire list-group-item. Because of this, I tried another way:

Javascript for adding delete icon before list-group-item:

var button = $('<button/>').text(result[key].deviceId).addClass('list-group-item device').attr({name:result[key].deviceId, "aria-label": "Quick View Device", "data-toggle": "modal", "data-target": "#quick-view-device-modal", type: "button"});
var deviceName = result[key].deviceId;
var deleteButton = $('<button/>').attr('type','button').attr('name','delete').attr('id',deviceName).html('<span class="glyphicon glyphicon-minus-sign red"></span>').addClass('icon delete-device');
$('#device-list').append(button);
$('button[name='+deviceName+']').before(deleteButton);
$('.delete-device').hide();


When I add the icon before each list-group-item, it comes out like this. The icon does nothing when I click it.
First of all, if I add the delete icon like this how would I make the icon line up with the item it corresponds with? Secondly, why is the click event for the icon not being triggered when I click it?

Answer

You could simply add a click event listener to your #device-list element and delegate the event to the button element. Inside the event handler callback check if the event target is the span or the button.

Here is an example, kind of trying to mimic the code you have in your question.

var result = {
  one: { deviceId: "dummy_one" },
  two: { deviceId: "dummy_two" },
  three: { deviceId: "dummy_three" }
}

var $deviceList = $('#device-list');
var $modal = $('#quick-view-device-modal');
var modalShowHndl = function (evt) {
  var button = evt.data.relatedTarget;
  $(this).find('.modal-title').html(button.text())
  $(this).find('.modal-body').html('<p>' + button.text() + '</p>')
}
var $relatedTarget;

for (var key in result) {
  var deviceName = result[key].deviceId;
  var button = $('<button/>')
  .text(' ' + deviceName)
  .addClass('list-group-item device')
  .attr({name:deviceName,
         "aria-label": "Quick View Device",
         "data-toggle": "modal",
         type: "button"});

  var deleteButton = $('<span/>')
  .attr({
    name: 'delete',
    id: deviceName
  })
  .addClass('icon delete-device glyphicon glyphicon-minus-sign red');

  button.prepend(deleteButton);
  $deviceList.append(button);
}

$deviceList.on('click', 'button', function(evt) {
  if($(evt.target).hasClass('glyphicon-minus-sign')) {
    console.log('delete device:',evt.target.parentNode.textContent)
  } else {
    $relatedTarget = $(evt.target);
    $modal.one('show.bs.modal', {relatedTarget: $relatedTarget}, modalShowHndl)
    $modal.modal('show')
  }
})
@import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<ul class="list-group" id="device-list"></ul>

<div id="quick-view-device-modal" class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body&hellip;</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

Comments