How to turn on/off sections using JavaScript with data-type

I have the following HTML to establish three buttons that I would like to filter out the list. So when the French button is clicked on, only the French listings will show, with the other two (or potentially more) becoming display:none.

<h2>Restaurants in New York</h2>
<input type="button" value="French" id="setFrench" />
<input type="button" value="Vegetarian" id="setVeg" />
<input type="button" value="German" id="setGerman" />

<ul>
  <li class="list" data-type="veg">Bloss</li>
  <li class="list" data-type="german">Heidelberg</li>
  <li class="list" data-type="french">Daniel</li>
  <li class="list" data-type="veg">Dirt Candy</li>
  <li class="list" data-type="french">La Grenouille</li>
  <li class="list" data-type="french">Balthazar</li>
  <li class="list" data-type="veg">Angelica Kitchen</li>
  <li class="list" data-type="german">Blaue Gans</li>
  <li class="list" data-type="german">Reichenbach Hall</li>
</ul>

Unfortunately, I think I am completely misunderstanding the role of data-type and its acquisition in JavaScript, for none of the scripts I’ve tried to piece together have succeeded. I thought I could do a getElementByClass to select the li, and select the data-type and somehow get them to target the “veg” and “german” to turn them to display:none (because we can’t turn a data-type to none) when the “French” button was pressed. Is this the right way to go? I must have tried about 6 different variations.

Can we use data-type to select all the items in JavaScript in order to set their display value? I’m just trying to learn data-type in a practical way to see if it’s something I can use in the future, especially for filtering like the above.

Hi there StevenHu,

here is an example for you to try…

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<!--<link rel="stylesheet" href="screen.css" media="screen">-->

<style media="screen">
.hide {
    display: none;
 }
</style>

</head>
<body> 

<div id="nojs" class="hide">

 <h1>Restaurants in New York</h1>

 <div id="buts">
  <input type="button" value="French">
  <input type="button" value="Vegetarian">
  <input type="button" value="German">
 </div>

 <ul id="menu">
  <li data-type="Vegetarian">Bloss</li>
  <li data-type="German">Heidelberg</li>
  <li data-type="French">Daniel</li>
  <li data-type="Vegetarian">Dirt Candy</li>
  <li data-type="French">La Grenouille</li>
  <li data-type="French">Balthazar</li>
  <li data-type="Vegetarian">Angelica Kitchen</li>
  <li data-type="German">Blaue Gans</li>
  <li data-type="German">Reichenbach Hall</li>
 </ul>

</div>

<script>
(function() {
   'use strict';

    var buts=document.getElementById('buts').getElementsByTagName('input'),
        lis=document.getElementById('menu').getElementsByTagName('li'),
        c;
    document.getElementById('nojs').classList.remove('hide');

for(c=0;c<lis.length;c++) {
    lis[c].classList.add('hide');
 } 
for(c=0;c<buts.length;c++) {
    buts[c].addEventListener('click',setClickHandler(c),false);
 } 
function  setClickHandler(c) {
    buts[c].onclick=function() {
for(c=0;c<lis.length;c++) {
if(this.value==lis[c].getAttribute('data-type')) {
    lis[c].classList.remove('hide');
 }
else {
    lis[c].classList.add('hide');
    }
   }
  };
 }
}());
</script>

</body>
</html>

coothead

Hi there StevenHu,

here is a CSS example for you to try…

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>untitled document</title>
<!--<link rel="stylesheet" href="screen.css" media="screen">-->
<style media="screen">
#r0, #r1, #r2 {
    position: absolute;
    left:-999em;
 }
label {
    display: inline-block;
    padding: 0.25em 0.5em;
    border: 0.1em solid #999;
    border-radius: 0.5em;
    background-image: linear-gradient(to bottom, #fff, #ccc);
    box-shadow: 0.25em 0.25em 0.25em #999;
    cursor: pointer;
 }
#menu li {
   display: none;
 }
#r0:checked~#menu li[data-type="French"],
#r1:checked~#menu li[data-type="Vegetarian"],
#r2:checked~#menu li[data-type="German"] {
    display: block;
 }
#r0:checked~label[for="r0"],
#r1:checked~label[for="r1"],
#r2:checked~label[for="r2"] {
    border: 0.1em solid #669;
    background-image: linear-gradient(to bottom, #fff, #ccf);
 }
</style>
</head>
<body> 
 <h1>Restaurants in New York</h1>
  <input type="radio" name="r" id="r0">
  <input type="radio" name="r" id="r1">
  <input type="radio" name="r" id="r2">
  <label for="r0">French</label>
  <label for="r1">Vegetarian</label>
  <label for="r2">German</label>
 <ul id="menu">
  <li data-type="Vegetarian">Bloss</li>
  <li data-type="German">Heidelberg</li>
  <li data-type="French">Daniel</li>
  <li data-type="Vegetarian">Dirt Candy</li>
  <li data-type="French">La Grenouille</li>
  <li data-type="French">Balthazar</li>
  <li data-type="Vegetarian">Angelica Kitchen</li>
  <li data-type="German">Blaue Gans</li>
  <li data-type="German">Reichenbach Hall</li>
 </ul>
</body>
</html>

coothead

you can select all elements of a specific data type by using:

var veg = document.querySelectorAll("li.list[data-type='veg']");
1 Like

Everything starting with data-* is a mere custom attribute; you can access those with the .dataset property in JS, like e.g.

const items = document.querySelectorAll('.list')

console.log(items[0].dataset) // {type: "veg"}
console.log(items[1].dataset) // {type: "german"}

You might the show/hide items by their data-type attribute like

function showType (type) {
  Array.from(items).forEach(item => {
    if (item.dataset.type === type) {
      item.style.display = 'block'
    } else {
      item.style.display = 'none'
    }
  })
}

// Call it like e.g.
showType('veg')

Thank you, everyone! I’ll have fun trying these out.

This works well!

Would I be able to make this more flexible by using class rather than data-type? That is, with changes to the function, could data-type=French become class=French German to basically house two data-types? Meaning, tapping French or German will both get the class above in addition to their respective class=French and class=German?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.