0

I'm trying to hide a DIV if it contains a ul with li with a specific text.

The one catch I have is that it can't be jQuery, pure JavaScript.

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>No upcoming events are scheduled </li>
  </ul>
</div>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • 1
    So select the div, read the text, see if the text has the string, if yes, hide it. – epascarello Sep 24 '18 at 17:16
  • Possible duplicate of [Javascript .querySelector find
    by innerTEXT](https://stackoverflow.com/questions/37098405/javascript-queryselector-find-div-by-innertext)
    – dustytrash Sep 24 '18 at 17:18
  • Something like `//div/ul/li[text()="No upcoming events are scheduled"]` (You can use xpath without jQuery as mentioned in the other post) – dustytrash Sep 24 '18 at 17:20
  • https://jsfiddle.net/q5Lofmzu/ Check if this is what you are asking for. – Void Spirit Sep 24 '18 at 17:54

5 Answers5

2

You can use https://www.w3schools.com/jsref/met_document_queryselector.asp. If you know how to write a CSS selector for jQuery, that's how you can use it without jQuery.

$('div > ul > li') becomes document.querySelectorAll("div > ul > li");

Of course:

  • I haven't selected the div, but the li.
  • I didn't check that the piece of text was included in the li.

So how do we do that? We can't do it with CSS selectors, so we're going to use plain JS. We'll filter only the li elements that contain the text we want, then we'll take their grand-parent node (which is the div).

// Get the li's in an array
let lis = Array.from(document.querySelectorAll("div > ul > li"));

// only keep the ones with the proper text
lis = lis.filter(item => item.text.match(/The text that you want to match/));

// get the div's from the li's
let divs = lis.map(item => item.parentNode.parentNode);

// do whatever you want to these divs.
...

This approach is more resilient than calling .innerHTML directly on the div, because in that scenario you might end up selecting div's with the required text somewhere random in their innerHTML. For instance something like:

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>No upcoming events are scheduled </li>
  </ul>
</div>

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <!--<li>No upcoming events are scheduled </li>-->
    <li>Event 1: 11/10 at 08:00</li>
  </ul>
</div>

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>Event 2: 12/10 at 08:00</li>
  </ul>
  <span>After that, you'll find out that No upcoming events are scheduled.</span>
</div>

Here with the .innerHTML methods from the other answers, all 3 div's are going to be hidden, instead of just the top one.

NicolasB
  • 966
  • 5
  • 9
0

You could do something like this. Get all the divs and find the ones with your requisite text and hide them. Please let me know if you would like clarification regarding the below code.

document.getElementById("hide").addEventListener("click", ()=>{
    let divs = document.getElementsByTagName("div");
    for(let i = 0;i<divs.length; i++){
      if(divs[i].innerHTML.includes("No upcoming events are scheduled")){
        divs[i].style.display = "none";
      }
    }
});
<div class="uc-events">
<h3 style="text-align: center;">Upcoming Events</h3>
<ul class="upcoming_events graphical_theme">
     <li>
   No upcoming events are scheduled  </li>
  </ul>

</div>

<button id="hide">hide divs</button>
Michael Sorensen
  • 1,850
  • 12
  • 20
0

var targetStr = "No upcoming events are scheduled";
var divs = document.getElementsByTagName("div");

for(var i = 0; i < divs.length; i++){
  var divsChildren = divs[i].children;
  for(var j = 0; j < divsChildren.length; j++){
    if(divsChildren[j].tagName == "UL"){
      var ulChildren = divsChildren[j].children;
      for(var k = 0; k < ulChildren.length; k++){
        if(ulChildren[k].tagName == "LI"){
          if(ulChildren[k].textContent.trim() === targetStr){
            divs[i].style.display = "none";
          }
        }
      }
    }
  }
}
<div id="num">first div</div>
<div class="uc-events">
<h3 style="text-align: center;">Upcoming Events</h3>
<ul class="upcoming_events graphical_theme">
     <li>
   No upcoming events are scheduled  </li>
  </ul>

</div>
<div id="num">third div</div>
Stakvino
  • 642
  • 4
  • 9
0

Check below snippet where I get all the div elements and check if their innerHTML contains given text. If you also want to check ul and li are present just add additional conditionals.

const divList = Array.prototype.slice.call(document.getElementsByTagName('DIV'));
console.log(divList);
divList.forEach((el) => {
  if (el.innerHTML.includes('No upcoming events are scheduled')) {
    el.style.display = 'none';
  }
})
<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>No upcoming events are scheduled </li>
  </ul>
</div>

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>No upcoming events are scheduled </li>
  </ul>
</div>

<div class="uc-events">
  <h3 style="text-align: center;">Upcoming Events</h3>
  <ul class="upcoming_events graphical_theme">
    <li>No upcoming events are schedu </li>
  </ul>
</div>
Shubham Gupta
  • 2,596
  • 1
  • 8
  • 19
-4

Ahh ok, i just edited the post, here is a simple way to hide ur LI if there is no text inside using javascript

 $('.testclass:empty').text("No News!");
<div class="testclass"></div>
    <div class="testclass">Div  with news</div>
    <div class="testclass"></div>
    
    
    
    <div class="uc-events">
      <h3 style="text-align: center;">Upcoming Events</h3>
      <ul class="testclass">
        <li><div class="testclass">IF NEWS DISPLAY DIV!</div></li>
      </ul>
    </div>