jmm
jmm

Reputation: 1064

Bootstrap and jQuery click event not working

I have a div element with a couple of inputs. When I started coding this, I had jQuery only, and my click event for the inputs was working properly.
Then, I added Bootstrap, and the event just stopped working.
This is the code

<!DOCTYPE html>
<html>
<head>
<title>Qué Pido?</title>
</head>
<body>

<p id="que-pido"></p>

<!-- jQuery and Bootstrap -->
<script
  src="https://code.jquery.com/jquery-3.1.1.min.js"
  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
  crossorigin="anonymous"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<script type="text/javascript">
  $(document).ready(function() {
    getFromEndpoint("clasicas");    
  });

  function getFromEndpoint(endpoint) {
    $(document).ready(function() {
      $.get( "que" + "/" + endpoint, function( data ) {
        console.log(data);
        $( "#que-pido" ).html( data );
      });
    });
  }

  $(document).ready(function() {
    $(".categorias").click(function() {
      console.log("clicked: " + $(this));
      var endpoint = $(this).attr('id');
      getFromEndpoint(endpoint);
    });
  });
</script>

<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-outline-primary active">
    <input type="radio" name="categorias" class="categorias" id="clasicas" autocomplete="off" checked> Cl&aacute;sicas
  </label>
  <label class="btn btn-outline-primary">
    <input type="radio" name="categorias" class="categorias" id="etnicas" autocomplete="off"> &Eacute;tnicas
  </label>
  <label class="btn btn-outline-primary">
    <input type="radio" name="categorias" class="categorias" id="todas" autocomplete="off"> Todas
  </label>
</div>

</body>
</html>

If I remove the labels, then the click method is properly fired... but of course, I get none of the CSS that Bootstrap provides.
I also tried removing Bootstrap's JS, but then I lose the animation that happens when pressing each button, and I'd like to keep that if possible.

Any ideas on this?
Thanks in advance

Upvotes: 2

Views: 2787

Answers (1)

B2K
B2K

Reputation: 2611

The reason that this doesn't work is that Bootstrap hides the input elements. You are actually clicking the label in a button set, not the actual elements.

var categoriasClicked = function() {
    console.log("clicked: " + $(this));
    var endpoint = $(this).attr('id');
    getFromEndpoint(endpoint);
}
$('.categorias').each(function() {
    if ($(this).closest('label').length > 0) {
        $(this).closest('label').click(function() {
            $(':radio', this).attr('checked', 'checked').each(categoriasClicked);
        });
    } else {
        $(this).click(categoriasClicked);
    }
}).filter(':checked').each(categoriasClicked);

Another aspect of Bootstrap button groups is that you end up losing the radio button. Here is some markup that adds a checkmark glyphicon.

<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-outline-primary active">
    <span class="glyphicon"></span>
    <input type="radio" name="categorias" class="categorias" id="clasicas" autocomplete="off" checked> Cl&aacute;sicas
  </label>
  <label class="btn btn-outline-primary">
    <span class="glyphicon"></span>
    <input type="radio" name="categorias" class="categorias" id="etnicas" autocomplete="off"> &Eacute;tnicas
  </label>
  <label class="btn btn-outline-primary">
    <span class="glyphicon"></span>
    <input type="radio" name="categorias" class="categorias" id="todas" autocomplete="off"> Todas
  </label>
</div>

<script type="text/javascript">
    var setIcons = function() {
        $('.glyphicon', this).addClass('glyphicon-unchecked').removeClass('glyphicon-check');
        $('.active .glyphicon', this).removeClass('glyphicon-unchecked').addClass('glyphicon-check');
    }
    $(document).on("click", '.btn-group', setIcons);
    $('.btn-group').each(setIcons);
</script>

See this fiddle https://jsfiddle.net/sdodvc3s/4/

EDIT: You'll notice in this code an unusual construct for handling the radio button clicks. The code for this is designed to handle radio click events in a somewhat agnostic way. It could be abstracted into a jQuery plugin like so:

$.fn.radioClick(function( callback ) {
    return this.each(function() {
        if ($(this).closest('label').length > 0) {
            $(this).closest('label').click(function() {
                $(':radio', this).attr('checked', 'checked').each(callback);
            });
        } else {
            $(this).click(callback);
        }
    });
});

And then used to handle any radio buttons on your page regardless of it's styling. Using the plugin, your code would become:

$('.categorias').radioClick(function() {
    console.log("clicked: " + $(this));
    var endpoint = $(this).attr('id');
    getFromEndpoint(endpoint);
}

Upvotes: 1

Related Questions