Toggling html buttons and text I went through a question on SO, and optimized the code according to OP's requirements. I would like a review if it is done properly or not.

Here is the code snippet, there are 2 level buttons, when clicked 1st level button, it toggles second level button group.

Second level button group toggles div, which contains checkbox. Any review and suggestions are appreciated.



$(document).ready(function() {

  var groups = ['a', 'b', 'c']; // here

  $.each(groups, function(k, id) {
    $('#' + id).hide();
    $('#' + id + 'l').hide();
  });

  $(".button").click(function() {

    var button_id = $(this).data('id');

    $('#' + button_id).toggle();

    var hide = $.grep(groups, function(value) {
      return value != button_id;
    });

    $.each(hide, function(k, id) {
      $('#' + id).hide();
    });

  });

  var selector = [];

  $.each(groups, function(k) {
    selector.push('.' + groups[k]);
  });

  selector = selector.join(',');

  $(selector).click(function() {

    var button_id = $(this).data('id');
    var class_id = $(this).attr('class');
    var flag = $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').is(':visible');

    $.each(groups, function(k, id) {
      $('#' + id + 'l').children().hide();
    });

    $.each(groups, function(k, id) {
      $('#' + id + 'l').hide();
    });

    $('#' + class_id + 'l').show();

    if (flag)
      $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').hide();
    else
      $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').show();
  });

});
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;button class="button" data-id="a"&gt;Toggle a&lt;/button&gt;
&lt;button class="button" data-id="b"&gt;Toggle b&lt;/button&gt;
&lt;button class="button" data-id="c"&gt;Toggle c&lt;/button&gt;

&lt;div id="a"&gt;
  &lt;div class="a" data-id="1"&gt;&lt;button&gt;Toggle a1&lt;/button&gt;&lt;/div&gt;
  &lt;div class="a" data-id="2"&gt;&lt;button&gt;Toggle a2&lt;/button&gt;&lt;/div&gt;
  &lt;div class="a" data-id="3"&gt;&lt;button&gt;Toggle a3&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div id="b"&gt;
  &lt;div class="b" data-id="1"&gt;&lt;button&gt;Toggle b1&lt;/button&gt;&lt;/div&gt;
  &lt;div class="b" data-id="2"&gt;&lt;button&gt;Toggle b2&lt;/button&gt;&lt;/div&gt;
  &lt;div class="b" data-id="3"&gt;&lt;button&gt;Toggle b3&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div id="c"&gt;
  &lt;div class="c" data-id="1"&gt;&lt;button&gt;Toggle c1&lt;/button&gt;&lt;/div&gt;
  &lt;div class="c" data-id="2"&gt;&lt;button&gt;Toggle c2&lt;/button&gt;&lt;/div&gt;
  &lt;div class="c" data-id="3"&gt;&lt;button&gt;Toggle c3&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div id="al"&gt;
  &lt;div class="al" data-id="1"&gt;this is line a1&lt;/div&gt;
  &lt;div class="al" data-id="2"&gt;this is line a2&lt;/div&gt;
  &lt;div class="al" data-id="3"&gt;this is line a3&lt;/div&gt;
&lt;/div&gt;

&lt;div id="bl"&gt;
  &lt;div class="bl" data-id="1"&gt;this is line b1&lt;/div&gt;
  &lt;div class="bl" data-id="2"&gt;this is line b2&lt;/div&gt;
  &lt;div class="bl" data-id="3"&gt;this is line b3&lt;/div&gt;
&lt;/div&gt;

&lt;div id="cl"&gt;
  &lt;div class="cl" data-id="1"&gt;this is line c1&lt;/div&gt;
  &lt;div class="cl" data-id="2"&gt;this is line c2&lt;/div&gt;
  &lt;div class="cl" data-id="3"&gt;this is line c3&lt;/div&gt;
&lt;/div&gt;
It's a bad practice to reuse a variable for multiple purposes, especially so when the types are different too: selector is first an array and then becomes a string.

Avoid duplication logic in both branches of a conditional like here: 


if (flag)
     $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').hide();
else
     $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').show();



Extract the dom selector with the filter, store the result in a variable, and in the branches of the if-else do the hide and show.

It's also recommended to use braces always, even with single statement if-else.

It seems to me that some operations could be joined together and done in a single .each, for example here:


$.each(groups, function(k, id) {
  $('#' + id + 'l').children().hide();
});

$.each(groups, function(k, id) {
  $('#' + id + 'l').hide();
});