Filter based on legend click

by fxi

HTML

<h4>Click on legend to filter values</h4>

<div class="mx-legend-container" id="divLegend">
  <div class="mx-legend">
    <input type="checkbox" id="1" data-filter='["==","cat","a"]'>
    <label for="1" class="mx-legend-content">
    <div class="mx-legend-color"  style="background-color:#ffeda0"></div>
    <div class="mx-legend-label">a</div>
</label>
  </div>
  <div class="mx-legend">
    <input type="checkbox" id="2" data-filter='["==","cat","b"]'>
    <label for="2" class="mx-legend-content">
<div class="mx-legend-color" style="background-color:#feb24c"></div>
    <div class="mx-legend-label">b</div>
</label>
  </div>
  <div class="mx-legend">
    <input type="checkbox" id="3" data-filter='["==","cat","c"]'>
    <label for="3" class="mx-legend-content">
<div class="mx-legend-color" style="background-color:#f03b20"></div>
    <div class="mx-legend-label">c</div>
</label>
  </div>
</div>

<pre id="preOut"></pre>
<button id="btnDestroy">remove listeners</button>

CSS

.mx-legend-container {
  display: flex;
  flex-direction: column;
}

.mx-legend>input {
  display: none;
}

.mx-legend>input:checked~.mx-legend-content:before {
  content: "=";
  margin: 0 3px 0 3px;
}

.mx-legend-color {
  height: 20px;
  width: 20px;
  background-color: #333;
  display: block;
}

.mx-legend-content {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.mx-legend-label {
  margin-left: 10px;
}

JavaScript

var filters = [];
var elLegendContainer;
var elButtonDestroy;
var elOut;
var toString = JSON.stringify;
var toObj = JSON.parse;

init();

/* Do something with filters */
function onUpdate(d) {
  elOut.innerText = JSON.stringify(filters)
}

/* Init ui*/
function init() {
  elOut = document.querySelector("#preOut");
  elButtonDestroy = document.querySelector("#btnDestroy");
  elLegendContainer = document.querySelector("#divLegend");
  elLegendContainer.addEventListener("click", update);
  elButtonDestroy.addEventListener("click", destroy);
  onUpdate(filters);
}

/* Update filters */
function update(e) {
  var el = e.target;
  if (el.dataset.filter) {
    e.stopImmediatePropagation();
    var filter = el.dataset.filter;
    var isChecked = el.checked;
    var filterPos = filters.findIndex(f =>
      toString(f) === filter
    );

    var hasFilter = filterPos > -1;

    if (isChecked && !hasFilter) {
      filters.push(toObj(filter));
    }

    if (!isChecked && hasFilter) {

      filters.splice(filterPos, 1);
    }
    onUpdate(filters);
  }
}

/*destroy listeners*/
;
function destroy() {
  if (elLegendContainer) {
    elLegendContainer.removeEventListener("click", update);
  }
}