Question

How can I assign class to each children in the following scenario:

Read data option value, and assign the same class name to children ul

<ul id="menu">
  <li data-option="first"> <a href="#">First Item</a>
    <ul>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
  <li data-option="second"> <a href="#">Second Item</a>
    <ul>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
  <li> <a href="#">Third Item</a>
    <ul>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
</ul>

The expected result should be:

<ul id="menu">
  <li data-option="first"> <a href="#">First Item</a>
    <ul class="first">
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
  <li data-option="second"> <a href="#">Second Item</a>
    <ul class="second">
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
  <li> <a href="#">Third Item</a>
    <ul>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
      <li><a href="#">Second level link</a></li>
    </ul>
  </li>
</ul>

Notice that last li dos not have data-option attribute.

Was it helpful?

Solution

another one to collection, filtering only the data-option li, reuse $ul object as much as possible

$(document).ready(function() {
    $('#menu>li[data-option]').each(function() {
        var $ul = $(this);
        $ul.find('ul').addClass($ul.data('option'));
    });
});

OTHER TIPS

You can use the has attribute selector ([]) to test for an attribute presence:

$('li[data-option]').each(function () {
    var dataOption = $(this).attr('data-option');
    $(this).find('ul').addClass(dataOption);
});

Check demo here.

Note: You could use .data('option') instead of .attr('data-option'). It is a matter of choice, really. In this case I used .attr() because .data() is more of a "storage" than an attribute accessor function - and, as you are plainly accessing the data-option attribute, with no conversion from the string value, the .attr() function seems to denote your intention in the code better.

Well, you could do this:

$('#menu > li').filter('[data-option]').each(function(){
   $(this).find('ul').addClass($(this).data('option');
});

using filter is good for performance as it allows jquery to use native querySelector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top