Dropdown test

by Hugo Carneiro

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="btn btn-primary fl-feature-filter">
  <i class="fa fa-filter"></i> Filter by features <span class="fl-feature-count hidden"></span>
  <div class="fl-feature-dropdown">
    <h4>Select the features</h4>
    <ul class="fl-dropdown-menu">
      <li>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="template-features" value="Directory"> Directory
          </label>
        </div>
      </li>
      <li>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="template-features" value="News feed"> News feed
          </label>
        </div>
      </li>
      <li>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="template-features" value="Discussion forum"> Discussion forum
          </label>
        </div>
      </li>
      <li class="divider"></li>
    </ul>
    <div class="fl-dropdown-footer">
      <div class="btn btn-default fl-btn-clear">Clear selection</div> 
    </div>
  </div>
</div>

CSS

.fl-feature-filter {
  position: absolute;
  right: 335px;
  top: 29px;
  background-color: #474974;
  border-color: #474974;
  border-radius: 44px;
  font-weight: 700;
  padding: 10px 16px;
  text-align: left;
}

.fl-feature-filter:hover,
.fl-feature-filter:focus,
.fl-feature-filter:active,
.fl-feature-filter:active:hover,
.fl-feature-filter:active:focus,
.fl-feature-filter.active,
.fl-feature-filter.active:hover {
  background-color: #474974;
  border-color: #474974;
  box-shadow: none;
}

.fl-feature-count {
  display: inline-block;
  background-color: #ffffff;
  color: #2c2f34;
  width: 18px;
  height: 18px;
  border-radius: 18px;
  text-align: center;
  line-height: 1.6;
  font-size: 12px;
  margin-left: 5px;
}

.fl-feature-dropdown {
  position: absolute;
  top: 40px;
  left: 0;
  background-color: #ffffff;
  color: #474974;
  border: 1px solid #D0D0D0;
  border-radius: 6px;
  margin-top: 5px;
  padding: 15px;
  font-weight: 400;
  box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.15);
  opacity: 0;
  visibility: hidden;
  cursor: default;
}

.fl-feature-filter.active .fl-feature-dropdown {
  opacity: 1;
  visibility: visible;
}

.fl-feature-dropdown h4 {
  margin-top: 0;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.1;
  color: #474974;
}

.fl-dropdown-menu {
  margin: 0;
  padding: 0;
  list-style: none;
}

.fl-dropdown-menu .checkbox {
  margin: 5px 0;
}

.fl-dropdown-menu .checkbox label {
  width: 100%;
}

.fl-dropdown-menu .divider {
  height: 1px;
  margin: 15px -15px;
  background-color: #D0D0D0;
}

.fl-dropdown-footer {
  display: flex;
  justify-content: flex-end;
}

JavaScript

var filterAppTemplates = {
  selectedFeatures: [],
  closeDropdown: function() {
    $('.fl-feature-filter').removeClass('active');
  },
  clearSelectedItems: function() {
    filterAppTemplates.selectedFeatures = [];

    $('.fl-feature-count').addClass('hidden');
    $('[name="template-features"]').prop('checked', false);
  },
  setSelectedItems: function() {
    $('.fl-feature-count')
      .text(filterAppTemplates.selectedFeatures.length)
      .toggleClass('hidden', !filterAppTemplates.selectedFeatures.length);
  },
  applyFilters: function() {
    if (!filterAppTemplates.selectedFeatures.length) {
      // TODO: Remove filters
      return;
    }

    // TODO: Apply filters
    console.log(filterAppTemplates.selectedFeatures);
  },
  attachEventListeners: function() {
    $(document).click(function(event) {
      var $target = $(event.target);

      if ($target.is('.fl-feature-filter')) {
        $target.toggleClass('active');

        return;
      }

      if (!$target.closest('.fl-feature-filter').length
        && $('.fl-feature-filter').hasClass('active')) {
          filterAppTemplates.closeDropdown();
      }
    });

    $('[name="template-features"]').on('change', function() {
      filterAppTemplates.selectedFeatures = [];

      $('[name="template-features"]').each(function() {
        if ($(this).is(':checked')) {
          filterAppTemplates.selectedFeatures.push($(this).val());
        }
      });

      filterAppTemplates.setSelectedItems();
      debouncedFilters();
    });

    $('.fl-btn-clear').on('click', function() {
      filterAppTemplates.clearSelectedItems();
    });
  },
  initialize: function() {
    filterAppTemplates.attachEventListeners();
  }
};
var debouncedFilters = _.debounce(filterAppTemplates.applyFilters, 1000);

filterAppTemplates.initialize();