1

I have a the grid of html elements, each with a data-category attribute on it.

Some data-category attributes have multiple values, separated by comma: data-category="category 2, category 3".

Some have single values: data-category="category 1", without a separator.

I use this simple script to filter the elements by category:

$('#category-selector').on('change', function(){
  var $item = $('#items-container').find('.item'),
      current = $(this).val();
    if(current == 'all'){
       $item.fadeIn(200);
    } else {
       $item.hide(200);
       $item.each(function(){
          var category = $(this).data('category').split(', ');
          //console.log(category);
          if($.inArray(current, category) >= 0){
            $(this).fadeIn(200);
          }
       });
    }
});
.posts-grid {
  margin-top: 25px;
}

.posts-grid>[class*='col-'] {
  display: flex;
  flex-direction: column;
  margin-bottom: 25px;
}

.posts-grid .block {
  background: #fff;
  border-top: 1px solid #d5d5d5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11);
}

.posts-grid p {
  margin: 0;
  text-align: center;
}

.posts-grid .block {
  flex-grow: 1;
  display: flex;
  justify-content: center;
  flex-direction: column;
}

.posts-grid .read-more {
  margin-top: auto;
}

@media (max-width: 767px) {
  .container {
    max-width: 100%;
  }
}

@media (max-width: 575px) {
  .container {
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
  }
  .posts-grid>[class*='col-'] {
    padding-left: 5px;
    padding-right: 5px;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />

<select id="category-selector">
  <option value="all">Select Category</option>
  <option value="category 1">Category 1</option>
  <option value="category 2">Category 2</option>
  <option value="category 3">Category 3</option>
</select>

<div class="container" id="items-container">
  <div class="posts-grid row">
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1, category 2">
      <div class="block">
        <div class="block">
          <p>1</p>
          <p>2</p>
        </div>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 2, category 3">
      <div class="block">
        <p>2</p>
        <p>3</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1, category 3">
      <div class="block">
        <p>1</p>
        <p>3</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <div class="block">
          <p>1</p>
        </div>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 2">
      <div class="block">
        <p>2</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <p>1</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <p>1</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <p>1</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <p>1</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1, category 2">
      <div class="block">
        <p>1</p>
        <p>2</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 2, category 3">
      <div class="block">
        <p>2</p>
        <p>3</p>
      </div>
    </div>
    <div class="item col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-category="category 1">
      <div class="block">
        <p>1</p>
      </div>
    </div>
  </div>
</div>

I was (pleasantly) surprised that my split(', ') method returns an array even if there is no separator.

Questions:

  1. Why does this happen?
  2. Is my filter reliable?
4
  • 1
    developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented May 16, 2019 at 20:35
  • 2
    Because that's how it's defined to behave. Commented May 16, 2019 at 20:36
  • Check that the string contains the delimiter before spliiting. Or check the array size after splitting. Commented May 16, 2019 at 20:38
  • If the API behavior changed based on how many elements were returned you’d have to check the return type every time you used it. Split returns an array. Empty, one element, n elements. Reliable, predictable and consistent. Commented May 16, 2019 at 20:44

2 Answers 2

2
  1. The split method is designed to work that way. From the documentation:

When found, separator is removed from the string and the substrings are returned in an array. If separator is not found or is omitted, the array contains one element consisting of the entire string.

If you want a method that behaves differently, you can write a wrapper on top of split() that returns something else when the string doesn't have the delimiter (what would you rather it return?)

  1. You filter still seems fine -- you are checking if the name of the category is in the array; if the array just consists of one element that corresponds to a category name, it'll be found; if the array consists of one element that is an empty string, it won't be found -- both are correct behaviors.
Sign up to request clarification or add additional context in comments.

Comments

0

From the Docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

It says:

If separator is not found or is omitted, the array contains one element consisting of the entire string.

So, split will always return an array. There is everything fine with your split() method

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.