2

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

6
  • Any errors in the dev console? Commented Dec 14, 2016 at 20:56
  • @j08691 no errors. The line console.log(data); isn't even logged Commented Dec 14, 2016 at 20:58
  • @Alexandru-Ionut Mihai sorry, I didn't understand what plugin you meant Commented Dec 14, 2016 at 20:59
  • Does removing the integrity and crossorigin attributes from your jQuery CDN link make any difference? Also, all your scripts and links should be in the head of your document, not the body. Commented Dec 14, 2016 at 21:00
  • @j08691 or at the bottom of the body instead of the top Commented Dec 14, 2016 at 21:37

1 Answer 1

1

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for your very detailed answer. Although it didn't seem to work as is, your "You are actually clicking the label in a button set, not the actual elements" comment made me think of setting the categorias class also to the labels, which made it work
Sorry, I didn't make myself clear: I just pasted the upper part (not the whole fiddle), and then added the class to the labels. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.