Home » Jquery » javascript – Save original data filter, unfiltered and unsorted-Exceptionshub

javascript – Save original data filter, unfiltered and unsorted-Exceptionshub

Posted by: admin February 24, 2020 Leave a comment

Questions:

I’m trying to save original data state to “all” filter. The content gets sorted and filtered by data attribute “data-filter”. So my output will be the original state unfiltered and unsorted. Note: the divs content that have the same “data-id” will be displayed only once.

So my desired output on “all” filter and when I first run the code will be:

  • content first
  • content second
  • content third
  • content fourth

Also for
– filter “one” the output will always be “content first”,
– filter “two” the ouput will be “content second” “content third”
…and so on

function removeDuplicates() {
  var content = $('.content');
  contentIds = content.map(function() {
    return $(this).data("id");
  }).toArray();
  var newSetContentIds = [...new Set(contentIds)];
  listedContent = $(newSetContentIds).map(function() {
    return $("[data-id=" + this + "]").first()[0];
  });

  listedContent.addClass('listed');
}

$('.filter').click(function() {

  var filterId = $(this).attr('data-filter');

  $('.content').hide();
  $('.content[data-filter=' + filterId + ']').addClass('active').show();

  removeDuplicates();
});
.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.listed {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="filter-container">
  <div class="filter" data-filter="all">
    all
  </div>
  <div class="filter" data-filter="1">
    one
  </div>
  <div class="filter" data-filter="2">
    two
  </div>
  <div class="filter" data-filter="3">
    three
  </div>
</div>

<div class="content-container">
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
  <div class="content" data-filter="2" data-id="15">
    content second
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="3" data-id="16">
    content fourth
  </div>
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
</div>
How to&Answer:

Your removeDuplicates function is not working. Also, it hinted that you want to run this function only the first time you press any of the filters.

Instead of using show() and hide() that apply inline display messing up with the .listed class, you can use another class .hidden to show or hide the divs.

Finally, it was no clear if you want to sort once or every time when the chosen filter is not “all”. Anyway, as mentioned, you can use flex property for the container and order property for the divs. It is inside removeDuplicates considering you want to sort divs once for all after the first click.

function removeDuplicates() {

    $(".filter").off("click", removeDuplicates);

    var content = $('.content');
    contentIds = content.map(function() {
        $(this).css('order', $(this).data("filter"));
        return $(this).data("id");
    }).toArray();

    var newContentIds = contentIds.filter((a, i, aa) => aa.indexOf(a) === i && aa.lastIndexOf(a) !== i);
    listedContent = $(newContentIds).map(function() {
        return $("[data-id=" + this + "]")[0];
    });


    listedContent.addClass('listed');
}

$(".filter").on("click", removeDuplicates);

$('.filter').click(function() {

    var filterId = $(this).attr('data-filter');

    if (filterId == "all") {
        $('.content').removeClass('hidden');
        return;
    }

    $('.content').addClass('hidden');
    $('.content[data-filter=' + filterId + ']').addClass('active').removeClass('hidden');
});
.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.hidden {
  display: none;
}

.content.listed {
  display: none;
}

.content-container {
  display: flex;
  flex-direction: column;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="filter-container">
  <div class="filter" data-filter="all">
    all
  </div>
  <div class="filter" data-filter="1">
    one
  </div>
  <div class="filter" data-filter="2">
    two
  </div>
  <div class="filter" data-filter="3">
    three
  </div>
</div>

<div class="content-container">
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
  <div class="content" data-filter="2" data-id="15">
    content second
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="3" data-id="16">
    content fourth
  </div>
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
</div>