Skip to content

Remove parent node on click of button throw function on found error

I’m working on my companies legacy project. It uses jQuery. I have to add a feature to it. The feature is that, on clicking a checkbox, a span with the checked value (let’s call it “filtered value”) will be displayed with a “remove” icon in it. On clicking the remove icon of the “filtered value”, filtered value should be removed and corresponding checkbox should be unchecked.

I got the first half working. But REMOVE functionality isn’t working. I get an error “ReferenceError, removeFilter is not defined.” Here is the Codesandbox.

var filtersApplied = [];
$('.ps-sidebar').on('change', 'input[type=checkbox]', function () {
  var me = $(this);
  console.log('me', me);
  if (me.prop('checked') === true) {
    filtersApplied.push(me.attr('data-filter-label'));
  } else {
    filtersApplied = filtersApplied.filter(function (filter) {
      return filter !== me.attr('data-filter-label');
    });
  }
  function removeFilter(el, filter) {
    console.log('im clicked', el);
    // el.remove();
  }

  if (filtersApplied.length === 0) {
    $('.ps-plans__filters').hide();
    $('.ps-plans__filters-applied').html('');
  } else {
    $('.ps-plans__filters').show();
    var filtersAppliedHtml = '';
    filtersApplied.forEach(function (filter) {
      filtersAppliedHtml +=
        '<span class="ps-plans__filter" id="' +
        filter +
        '">' +
        filter +
        '<span class="remove" onclick="removeFilter(this, filter)">x</span></span>';
    });
    console.log('filtersAppliedHtml', filtersAppliedHtml);
    $('.ps-plans__filters-applied').html(filtersAppliedHtml);
  }
});

Answer

Several problems:

  1. removeFilter() needs to be declared globally, i.e. outside the “on change” handler.
  2. You need to pass the correct ID to removeFilter().
  3. removeFilter() needs to remove the parent <span> as well as uncheck the corresponding checkbox.
  4. When clicking the “X” to remove a filter, you need to remove it from the filtersApplied array.

Here’s a working model:

// https://stackoverflow.com/a/5767357/378779
function removeItemOnce(arr, value) {
  var index = arr.indexOf(value);
  if (index > -1) {
    arr.splice(index, 1);
  }
  return arr;
}

function removeFilter(el, filter) {
    console.log('im clicked', el);
    $('input[id="' + filter + '"]').prop('checked', false)
    $(el).parent().remove();
    filtersApplied = removeItemOnce( filtersApplied, filter ); // Remove item from filter
}

var filtersApplied = [];
$('.ps-sidebar').on('change', 'input[type=checkbox]', function () {
  var me = $(this);
  console.log('me', me);
  if (me.prop('checked') === true) {
    filtersApplied.push(me.attr('data-filter-label'));
  } else {
    filtersApplied = filtersApplied.filter(function (filter) {
      return filter !== me.attr('data-filter-label');
    });
  }

  if (filtersApplied.length === 0) {
    $('.ps-plans__filters').hide();
    $('.ps-plans__filters-applied').html('');
  } else {
    $('.ps-plans__filters').show();
    var filtersAppliedHtml = '';
    filtersApplied.forEach(function (filter) {
      filtersAppliedHtml +=
        '<span class="ps-plans__filter" id="' +
        filter +
        '">' +
        filter +
        `<span class="remove" onclick="removeFilter(this, '${filter}')">x</span></span>`;
    });
    console.log('filtersAppliedHtml', filtersAppliedHtml);
    $('.ps-plans__filters-applied').html(filtersAppliedHtml);
  }
});
.hide {
  display: none;
}
.ps-plans__filters-container {
  margin-top: 30px;
}
.ps-plans__filter {
  border: 1px solid #000;
  border-radius: 4px;
  padding: 5px 10px;
  width: 100px;
  margin-right: 20px;
}
.remove {
  border: 1px solid #000;
  border-radius: 50%;
  margin-left: 10px;
  padding-top: 3px;
  padding-bottom: 3px;
  padding-right: 5px;
  padding-left: 5px;
}
<html>
  <head>
    <title>jQuery button interactive sample</title>
    <meta charset="UTF-8" />
<script
src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"></script>

  </head>

  <body>
    <div class="wrapper">
      <div id="cblist" class="ps-sidebar">
        <input type="checkbox" value="HSA" id="hsa" data-filter-label="hsa" />
        <label for="cb1">HSA</label>

        <input type="checkbox" value="PCO" id="pco" data-filter-label="pco" />
        <label for="cb1">PCO</label>
      </div>
      <div class="ps-plans__filters-container">
        <div class="ps-plans__filters hide">
          <span class="ps-plans__filters-label">
            Filtered Value
          </span>
          <span class="ps-plans__filters-applied"></span>
        </div>
      </div>
    </div>

  </body>
</html>