skip to Main Content

I have the following html structure

<div id="container">
    <div id="child_1" data-customId="100">
    </div>
    <div id="child_2" data-customId="100">
    </div>
    <div id="child_3" data-customId="100">
    </div>
    <div id="child_4" data-customId="20">
    </div>
    <div id="child_5" data-customId="323">
    </div>
    <div id="child_6" data-customId="14">
    </div>
</div>

And what I want to do is to get the count of child divs that contains different data attribute. For example, I’m trying this:

$(`div[id*="child_"]`).length); // => 6

But that code is returning 6 and what I want to retrieve is 4, based on the different data-customId. So my question is, how can I add a filter/map to that selector that I already have but taking into consideration that is a data-attribute.

I was trying to do something like this:

var divs = $(`div[id*="child_"]`);
var count = divs.map(div => div.data-customId).length;

2

Answers


  1. You’ll have to extract the attribute value from each, then count up the number of uniques.

    const { size } = new Set(
      $('[data-customId]').map((_, elm) => elm.dataset.customid)
    );
    console.log(size);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="container">
        <div id="child_1" data-customId="100">
        </div>
        <div id="child_2" data-customId="100">
        </div>
        <div id="child_3" data-customId="100">
        </div>
        <div id="child_4" data-customId="20">
        </div>
        <div id="child_5" data-customId="323">
        </div>
        <div id="child_6" data-customId="14">
        </div>
    </div>

    No need for jQuery for something this trivial, though.

    const { size } = new Set(
      [...document.querySelectorAll('[data-customId]')].map(elm => elm.dataset.customid)
    );
    console.log(size);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="container">
        <div id="child_1" data-customId="100">
        </div>
        <div id="child_2" data-customId="100">
        </div>
        <div id="child_3" data-customId="100">
        </div>
        <div id="child_4" data-customId="20">
        </div>
        <div id="child_5" data-customId="323">
        </div>
        <div id="child_6" data-customId="14">
        </div>
    </div>

    Note that the property customid is lower-cased in the JavaScript. This could be an easy point of confusion. You might consider changing your HTML from

    data-customId="14"
    

    to

    data-custom-id="14"
    

    so that you can use customId in the JS (to follow the common conventions).

    Login or Signup to reply.
  2. After you getting the child-divs map their customid and just get the length of unique values:

    let divs = document.querySelectorAll(`div[id*="child_"]`);
    let idCustoms = [...divs].map(div=>div.dataset.customid);
    //idCustoms: ["100", "100", "100", "20", "323", "14"]
    //get unique values with Set 
    console.log([... new Set(idCustoms)].length);//4
    //or with filter
    console.log(idCustoms.filter((item, i, ar) => ar.indexOf(item) === i).length);//4
    <div id="container">
        <div id="child_1" data-customId="100">
        </div>
        <div id="child_2" data-customId="100">
        </div>
        <div id="child_3" data-customId="100">
        </div>
        <div id="child_4" data-customId="20">
        </div>
        <div id="child_5" data-customId="323">
        </div>
        <div id="child_6" data-customId="14">
        </div>
    </div>

    Note: $ is equivalent to document.querySelectorAll in js returns a NodeList that’s why I destructure it by the three dots ...

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search