0

I am using listjs and have the following code where you can filter the list according to a predefined text.

In the following snippet you should be able to filter by [All, 1900 or 2000] but if you tried to filter by the year - it does not work.

From the console log I could gather that at if (item.values().rsc-born == $val) in the filter function, .rsc-born is not taken as css selector and instead this is returned born is not defined.

var options = {
  valueNames: ['rsc-name', 'rsc-born'],
};

var userList = new List('users', options);

$('#filter-none').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  userList.filter();
  return false;
});

$('#filter-1').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values().rsc-born == $val) {
      return true;
    } else {
      return false;
    }
  });
  return false;
});

$('#filter-2').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values().rsc-born == $val) {
      return true;
    } else {
      return false;
    }
  });
  return false;
});
.rsc-filter-item:hover {
  text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<div id="users">

  <input class="search" placeholder="Search" />

  <ul class="rsc-filter filter">
    Filter by year<br>
    <li class="rsc-filter-item active" id="filter-none">Show All</li>
    <li class="rsc-filter-item" id="filter-1">1900</li>
    <li class="rsc-filter-item" id="filter-2">2000</li>
  </ul>

  <ul class="list">
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc-born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc-born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Martina</h3>
      <p class="rsc-born">1900</p>
    </li>
    <li>
      <h3 class="rsc-name">Gustav</h3>
      <p class="rsc-born">1900</p>
    </li>
  </ul>

</div>

So I renamed rsc-born to rsc_born as you can see in the snippet below and it works like a charm. I assume the - in between rsc and born is considered as an operator which is why it is trying to find the value of born?

var options = {
  valueNames: ['rsc-name', 'rsc_born'],
};

var userList = new List('users', options);

$('#filter-none').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  userList.filter();
  return false;
});

$('#filter-1').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values().rsc_born == $val) {
      return true;
    } else {
      return false;
    }
  });
  return false;
});

$('#filter-2').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values().rsc_born == $val) {
      return true;
    } else {
      return false;
    }
  });
  return false;
});
.rsc-filter-item:hover {
  text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<div id="users">

  <input class="search" placeholder="Search" />

  <div class="rsc-filter filter">
    Filter by year<br><br>
    <div class="rsc-filter-item active" id="filter-none">Show All</div>
    <div class="rsc-filter-item" id="filter-1">1900</div>
    <div class="rsc-filter-item" id="filter-2">2000</div>
  </div>

  <ul class="list">
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc_born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc_born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Martina</h3>
      <p class="rsc_born">1900</p>
    </li>
    <li>
      <h3 class="rsc-name">Gustav</h3>
      <p class="rsc_born">1900</p>
    </li>
  </ul>

</div>

I am new to JS and I have no idea how to make the code work without having to rename the css selector. Is there any way to achieve this? or at least, someone who can explain what is wrong with the way I am using it now.

CD001
  • 8,332
  • 3
  • 24
  • 28
Shahril Amri
  • 3
  • 1
  • 4
  • Your assumption is correct. Javascript will try to subtract born from rsc in you first notation. It's dot notation vs. bracket notation: Read all about it here: https://stackoverflow.com/questions/4968406/javascript-property-access-dot-notation-vs-brackets – Mouser Nov 03 '17 at 08:54
  • I don't know about the dot & bracket notation thing. Really need to go and polish my basics. Thank you @Mouser – Shahril Amri Nov 03 '17 at 09:02
  • 1
    Bracket notation is the "work-around". The actual problem is that `rsc-born` is not a valid variable name, imho, this is the better duplicate: [How to access object property with invalid characters](https://stackoverflow.com/questions/21056075/how-to-access-object-property-with-invalid-characters) – Andreas Nov 03 '17 at 09:03

1 Answers1

0

You need to use a different method to reference a property when the property name itself is not a valid identifier.

obj.prop is the same as obj['prop']

As such, the following small change works:

var options = {
  valueNames: ['rsc-name', 'rsc-born'],
};

var userList = new List('users', options);

$('#filter-none').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  userList.filter();
  return false;
});

$('#filter-1').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values()['rsc-born'] == $val) { // Change #1
      return true;
    } else {
      return false;
    }
  });
  return false;
});

$('#filter-2').click(function() {
  $('.rsc-filter .rsc-filter-item').removeClass('active');
  $(this).addClass('active');
  $val = this.innerHTML;
  userList.filter(function(item) {
    if (item.values()['rsc-born'] == $val) { // Change #2
      return true;
    } else {
      return false;
    }
  });
  return false;
});
.rsc-filter-item:hover {
  text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<div id="users">

  <input class="search" placeholder="Search" />

  <ul class="rsc-filter filter">
    Filter by year<br>
    <li class="rsc-filter-item active" id="filter-none">Show All</li>
    <li class="rsc-filter-item" id="filter-1">1900</li>
    <li class="rsc-filter-item" id="filter-2">2000</li>
  </ul>

  <ul class="list">
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc-born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Jonny</h3>
      <p class="rsc-born">2000</p>
    </li>
    <li>
      <h3 class="rsc-name">Martina</h3>
      <p class="rsc-born">1900</p>
    </li>
    <li>
      <h3 class="rsc-name">Gustav</h3>
      <p class="rsc-born">1900</p>
    </li>
  </ul>

</div>
Phylogenesis
  • 7,775
  • 19
  • 27