Dmitry
Dmitry

Reputation: 61

How do I split a string into an array for list.js and include a search on it?

How do I split a string into an array for list.js and include a search on it?

For ease of understanding: there is a block, like: <p class="born">1986, 1990, 2001</p>.

In my case, all three values individually should go in the drop-down list and work as a filter. I honestly tried to find something in the documentation, but couldn't.

I tried using different combinations of .split(", "), and found this cumbersome example: https://codepen.io/JasonEspin/pen/bdajKo

Is there a simpler way to get an array with delimiters?

var options = { valueNames: [ 'name', 'born' ] };
var userList = new List('users', options);
  
var updateList = function(){
  var values_date = $(".date_s").val()
  var values_name = $(".name_s").val()
  
  userList.filter(function(item) {
    return (_(values_date).contains(item.values().born) || !values_date) 
           && (_(values_name).contains(item.values().name) || !values_name)
  });
}
                               
$(function(){
  updateList();
  $(".date_s").change(updateList);
  $(".name_s").change(updateList);
  
  var all_born = [];
  var all_name = [];

  _(userList.items).each(function(item){
    all_born.push(item.values().born)
    all_name.push(item.values().name)  
  });
  
  _(all_born).uniq().each(function(item){
    $(".date_s").append('<option value="'+item+'">'+ item +'</option>')
  });
  _(all_name).uniq().each(function(item){
    $(".name_s").append('<option value="'+item+'">'+ item +'</option>')
  }); 
  
  $('select').each(function(){
    $(this).multipleSelect({
      onClick: updateList,
      selectAll: false,
      placeholder: $(this).data('placeholder')
    });
  });
  
});
.list {
  font-family:sans-serif;
  margin:0;
  padding:20px 0 0;
}
.list > li {
  display:block;
  background-color: #eee;
  padding:10px;
  box-shadow: inset 0 1px 0 #fff;
}
.avatar {
  max-width: 150px;
}
img {
  max-width: 100%;
}
h3 {
  font-size: 16px;
  margin:0 0 0.3rem;
  font-weight: normal;
  font-weight:bold;
}
p {
  margin:0;
}

input {
  border:solid 1px #ccc;
  border-radius: 5px;
  padding:7px 14px;
  margin-bottom:10px
}
input:focus {
  outline:none;
  border-color:#aaa;
}
.sort {
  padding:8px 30px;
  border-radius: 6px;
  border:none;
  display:inline-block;
  color:#fff;
  text-decoration: none;
  background-color: #28a8e0;
  height:30px;
}
.sort:hover {
  text-decoration: none;
  background-color:#1b8aba;
}
.sort:focus {
  outline:none;
}
.sort:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid transparent;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
.sort.asc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #fff;
  content:"";
  position: relative;
  top:13px;
  right:-5px;
}
.sort.desc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #fff;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users">
  <input class="search" placeholder="Search" />
  <select class="date_s" style="width:120px;" data-placeholder="Choose a date">
  </select>
  <select id="multiple-checkboxes" class="name_s" multiple style="width:150px;" data-placeholder="Choose a name">
  </select>
  
  
  <ul class="list">
    <li>
      <h3 class="name">Jonny Wayne</h3>
      <p class="born">1986, 1990, 2001</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985, 2000</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>    
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>
    <li>
      <h3 class="name">Martina</h3>
      <p class="born">1986</p>
    </li>
    <li>
      <h3 class="name">Gustaf</h3>
      <p class="born">1983</p>
    </li>
  </ul>

</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/multiple-select.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://unpkg.com/[email protected]/dist/multiple-select.min.js"></script>

Upvotes: 0

Views: 565

Answers (2)

fdomn-m
fdomn-m

Reputation: 28621

You can either add separated (split()) values to your all_born array

all_born.push(...item.values().born.split(","))

or split the all_born at time of adding to the select, eg:

_(all_born).uniq().each(function(item){
  item.split(",").forEach((i,txt) => 
      $(".date_s").append('<option value="'+txt+'">'+ txt +'</option>')
  );
});

In the filter part, your 'values_date' will only be a single value as it's not multi-select, so you can use vanilla js array.includes(value) to check each item's list of values:

item.values().born.split(", ").includes(values_date) 

Updated snippet below.

Added a "blank" entry in date to be able to clear it. Added .sort() so the years appear in a usable order and changed the split to .split(", ") so that the sort works. If you have mixed "," and ", " separators, then you'll either need to split on a regex or trim the values.

var options = { valueNames: [ 'name', 'born' ] };
var userList = new List('users', options);
  
var updateList = function(){
  var values_date = $(".date_s").val()
  var values_name = $(".name_s").val()
  
  userList.filter(function(item) {
    return (item.values().born.split(", ").includes(values_date) || !values_date) 
           && (_(values_name).contains(item.values().name) || !values_name)
  });
}
                               
$(function(){
  updateList();
  //$(".date_s").change(updateList);
  //$(".name_s").change(updateList);
  
  var all_born = [];
  var all_name = [];

  _(userList.items).each(function(item){
    all_born.push(...item.values().born.split(", "))
    all_name.push(item.values().name)  
  });
  
  _(all_born).uniq().sort().each(function(item){
    $(".date_s").append('<option value="'+item+'">'+ item +'</option>')
  });
  _(all_name).uniq().each(function(item){
    $(".name_s").append('<option value="'+item+'">'+ item +'</option>')
  }); 
  
  $('select').each(function(){
    $(this).multipleSelect({
      onClick: updateList,
      selectAll: false,
      placeholder: $(this).data('placeholder')
    });
  });
  
});
.list {
  font-family:sans-serif;
  margin:0;
  padding:20px 0 0;
}
.list > li {
  display:block;
  background-color: #eee;
  padding:10px;
  box-shadow: inset 0 1px 0 #fff;
}
.avatar {
  max-width: 150px;
}
img {
  max-width: 100%;
}
h3 {
  font-size: 16px;
  margin:0 0 0.3rem;
  font-weight: normal;
  font-weight:bold;
}
p {
  margin:0;
}

input {
  border:solid 1px #ccc;
  border-radius: 5px;
  padding:7px 14px;
  margin-bottom:10px
}
input:focus {
  outline:none;
  border-color:#aaa;
}
.sort {
  padding:8px 30px;
  border-radius: 6px;
  border:none;
  display:inline-block;
  color:#fff;
  text-decoration: none;
  background-color: #28a8e0;
  height:30px;
}
.sort:hover {
  text-decoration: none;
  background-color:#1b8aba;
}
.sort:focus {
  outline:none;
}
.sort:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid transparent;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
.sort.asc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #fff;
  content:"";
  position: relative;
  top:13px;
  right:-5px;
}
.sort.desc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #fff;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users">
  <input class="search" placeholder="Search" />
  <select class="date_s" style="width:120px;" data-placeholder="Choose a date">
    <option value="">Choose a date</option>
  </select>
  <select id="multiple-checkboxes" class="name_s" multiple style="width:150px;" data-placeholder="Choose a name">
  </select>
    
  <ul class="list">
    <li>
      <h3 class="name">Jonny Wayne</h3>
      <p class="born">1986, 1990, 2001</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985, 2000</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>    
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>
    <li>
      <h3 class="name">Martina</h3>
      <p class="born">1986</p>
    </li>
    <li>
      <h3 class="name">Gustaf</h3>
      <p class="born">1983</p>
    </li>
  </ul>

</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/multiple-select.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://unpkg.com/[email protected]/dist/multiple-select.min.js"></script>


In the case that you change your year to be multiple as well, you need to use an "intersects" construct:

return !values_date || item.values().born.split(", ").some(r=>values_date.includes(r))

Note that you should put !values_date first as js evaluates left-to-right and if values_date is null, then having it on the right will give an error.

Updated snippet for multiple years (using "or" as it does with the names).

var options = { valueNames: [ 'name', 'born' ] };
var userList = new List('users', options);
  
var updateList = function(){
  var values_date = $(".date_s").val()
  var values_name = $(".name_s").val()
  
  userList.filter(function(item) {
    return (!values_date || item.values().born.split(", ").some(r=>values_date.includes(r))) 
           && (!values_name || _(values_name).contains(item.values().name))
  });
}
                               
$(function(){
  updateList();
  //$(".date_s").change(updateList);
  //$(".name_s").change(updateList);
  
  var all_born = [];
  var all_name = [];

  _(userList.items).each(function(item){
    all_born.push(...item.values().born.split(", "))
    all_name.push(item.values().name)  
  });
  
  _(all_born).uniq().sort().each(function(item){
    $(".date_s").append('<option value="'+item+'">'+ item +'</option>')
  });
  _(all_name).uniq().each(function(item){
    $(".name_s").append('<option value="'+item+'">'+ item +'</option>')
  }); 
  
  $('select').each(function(){
    $(this).multipleSelect({
      onClick: updateList,
      selectAll: false,
      placeholder: $(this).data('placeholder')
    });
  });
  
});
.list {
  font-family:sans-serif;
  margin:0;
  padding:20px 0 0;
}
.list > li {
  display:block;
  background-color: #eee;
  padding:10px;
  box-shadow: inset 0 1px 0 #fff;
}
.avatar {
  max-width: 150px;
}
img {
  max-width: 100%;
}
h3 {
  font-size: 16px;
  margin:0 0 0.3rem;
  font-weight: normal;
  font-weight:bold;
}
p {
  margin:0;
}

input {
  border:solid 1px #ccc;
  border-radius: 5px;
  padding:7px 14px;
  margin-bottom:10px
}
input:focus {
  outline:none;
  border-color:#aaa;
}
.sort {
  padding:8px 30px;
  border-radius: 6px;
  border:none;
  display:inline-block;
  color:#fff;
  text-decoration: none;
  background-color: #28a8e0;
  height:30px;
}
.sort:hover {
  text-decoration: none;
  background-color:#1b8aba;
}
.sort:focus {
  outline:none;
}
.sort:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid transparent;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
.sort.asc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #fff;
  content:"";
  position: relative;
  top:13px;
  right:-5px;
}
.sort.desc:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #fff;
  content:"";
  position: relative;
  top:-10px;
  right:-5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users">
  <input class="search" placeholder="Search" />
  <select class="date_s" style="width:120px;" multiple data-placeholder="Choose a date">
    <option value="">Choose a date</option>
  </select>
  <select id="multiple-checkboxes" class="name_s" multiple style="width:150px;" data-placeholder="Choose a name">
  </select>
    
  <ul class="list">
    <li>
      <h3 class="name">Jonny Wayne</h3>
      <p class="born">1986, 1990, 2001</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985, 2000</p>
    </li>
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>    
    <li>
      <h3 class="name">Jonas</h3>
      <p class="born">1985</p>
    </li>
    <li>
      <h3 class="name">Martina</h3>
      <p class="born">1986</p>
    </li>
    <li>
      <h3 class="name">Gustaf</h3>
      <p class="born">1983</p>
    </li>
  </ul>

</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/multiple-select.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://unpkg.com/[email protected]/dist/multiple-select.min.js"></script>

Upvotes: 1

Dmitry
Dmitry

Reputation: 61

Assuming the example works, this method is guaranteed to work for the output to the list

instead:

  _(userList.items).each(function (item) {
    all_born.push(item.values().born);
    all_name.push(item.values().name);
  });

Insert this

    _(userList.items).each(function (item) {
    if (item.values().born.indexOf(",") > 0) {
      var arr = item.values().born.split(",");
      all_born = all_born.concat(arr);
    } else {
      all_born.push(item.values().born);
    }
    all_name.push(item.values().name);
  });

or it, which also works, although...

  _(userList.items).each(function(item){
    all_born.push(...item.values().born.split(","))
    all_name.push(item.values().name)  
  });

While I'm looking for a solution to filter the list...

Upvotes: 0

Related Questions