Hiding an unordered list when it has no elements - javascript

I have a problem that seems at first like a total no-brainer and an easy task.
I have a JavaScript plugin on my page that generates a Table Of Contents list to the sidebar of my Wordpress pages. My purpose is to hide the text widget element of the #toc when the list within it has no elements. I'm trying to solve it using jQuery but no luck.
The HTML:
<div class="textwidget">
<div id="toc">
<ul></ul>
</div>
</div>
The JavaScript:
jQuery(document).ready(function ($) {
if (!$('#toc').children('ul').has('li')) {
$('#toc').parent().hide();
}
});
My script should hide this specific #toc's parent, because it has no child <li> elements, but it doesn't. Instead, when I remove the ! from my if sentence, the script hides my list, as if it had something in it. It then also hides the lists that actually have elements in them. Am I totally missing something here?

Simply use this:
$(document).ready(function () {
if ($('#toc ul li').length < 1) {
$('#toc').parent().hide();
}
});

<script>
$(document).ready(function(){
$("#YourListID").hide();
var a = $("#YourListID li").length();
if (a > 0 ) {
$("#YourListID").show();
}
else {
$("#YourListID").hide();
}
});
</script>

You can try one of the following:
1) Give the UL an ID and check it's HTML. Ex:
var ulHtml = $("#myULElement").html();
if(ulHtml == ''){
$('#toc').parent.hide();
}
2) Do the same as above but with a relative path, like:
var ulHtml = $("#toc ul").html();
//etc...
See if that works. If it does, we can elaborate on it further.

This works:
if(!$('#toc').has('ul li').length) {
$('#toc').closest('.textwidget').hide();
}
Working jsfiddle here

What you need to do is add .length to your testing statement.
jQuery(document).ready(function ($) {
if (!$('#toc').children('ul').has('li').length) {
$('#toc').parent().hide();
}
});
Working Fiddle
Source: http://api.jquery.com/has/

Use length to evaluate if there are <li> or not.
DEMO
<div class="textwidget">
<div id="toc">
<ul></ul>
</div>
</div>
if ($('#toc ul li').length<1) {
$('#toc').parent().hide();
}

inside $(document).ready check for this
if($.trim($('#toc ul').html()).length == 0){
$('#toc').parent().hide();
}
as case may arise
<ul></ul>
<ul>
</ul>

Related

Wrap a tag around href inside a div

In the HTML code there is a 'href' , is there any posiblity to wrap an A-tag() around it? I'm new to this so please don't be too harsh :)
Note that the jquery is there to find the 'href' of a child inside the div and setting that attritbute to .summary-item-wrapper
HTML:
<div class="summary-item-wrapper" href="www.google.no" id="yui_3_17_2_4_1483527702805_1738"><div>
Jquery:
$(document).ready(function(){
$('body').wrapInner('<div id="support"></div>');
$('#support .sqs-block-summary-v2 .summary-item').each(function () {
var linkto = $(this).find('.summary-title a').attr('href');
$(this).children('.summary-item-wrapper').attr('href', linkto);
});
});
If there are multiple divs on your page you wish to convert, and to remove divs, but to keep all attributes, you can do something like this:
$( "div.summary-item-wrapper" ).each(function() {
$(this).before('<a href=http://'+$(this).attr('href') +'>A link');
$(this).prev().attr('id',$(this).attr('id'));
$(this).prev().addClass($(this).attr('class'));
});
$('div.summary-item-wrapper').remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="summary-item-wrapper" href="www.google.no" id="yui_3_17_2_4_1483527702805_1738">44444444444</div>
<div class="summary-item-wrapper" href="www.google.com" id="yui_3_17_2_4_1483527702805_33333">ttttttttttt</div>
What you want can be done with this:
$('#support .sqs-block-summary-v2 .summary-item-wrapper').wrap(function () {
return '';
});
Also href="google.no" means go to <currentdomain>/google.no, in case you need the google.no use href="https://google.no"
Check JSFiddle.
Please consider the comments on your question too.

Targeting specific elements in JavaScript?

I tried asking this before, but I guess I wasn't specific enough. Suppose I have HTML code that looks like this. How do I ONLY target the tags within the the horizontalNAV using pure JavaScript? Okay I know I could do this using jQuery like this...
<script type="text/javascript">
$(document).ready(function(){
$('#horizontalNAV li a').click(function(){
//jQuery code here...
});
});
</script>
However I do NOT want a jQuery answer, because I want to know how you target ('#horizontalNAV li a') using pure javaScript.
or you can tell me how to do it for the verticalNav portion, either way I'll get it, if I see an example or if its explained to me. If I'm not mistaken you would have to use the document.querySelectorAll method, if so, how does that work in the above example.
<div id="wrapper">
<div id="horizontalNav">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
</div>
<div class="sideBar">
<div class="verticalNav">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
</div>
</div>
</div>
Without jQuery it would look like this
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
var elems = document.querySelectorAll('#horizontalNav li a');
for (var i = elems.length; i--;)
elems[i].addEventListener("click", handler, false);
}, false);
function handler(event) {
//javascript code here...
this.style.color = 'red';
}
</script>
FIDDLE
If #horizontalNAV is a UL or OL element, then it can only have LI element children so you can skip that part of the selector. The following doesn't use querySelectorAll so will work in browsers, that don't support it:
<script>
window.onload = function() {
var list = document.getElementById('#horizontalNAV');
var links = list && list.getElementsByTagName(‘a’);
if (links) {
for (var i=0, iLen=links.length; i<iLen; i++) {
links[i].onclick = listener;
}
}
}
function listener() {
// do stuff
}
</script>
If you want to include more than one listener for an event, you’ll need to use addEventListener or some other strategy instead of assigning the function directly to the element, but in most cases only one listener is required per event type and keeping things simple has its benefits.
The listener function is declared outside the function doing the assignment to avoid a closure and circular reference, so it should have less chance of creating a memory leak.

jQuery .length or .size

i've got this function as per below:
$(".selectedItems").on('click', '.deleteItem', function (event) {
$(this).parent().remove();
if ($(this).parent('.selectedItems').children().length === 0) {
alert('hello');
}
});
in conjunction with the following html:
<div class="selectedItems">
<div class="item">
</div>
<div class="item">
</div>
</div>
<div class="selectedItems">
<div class="item">
</div>
<div class="item">
</div>
</div>
The problem is that the size is always showing up as 0 regardless and my if statement keeps on triggering, i been looking at this code for a while.. im not sure about what can be the problem.
You can find a link to the jsfiddle here: http://jsfiddle.net/kmcbride/UpGgQ/6/
As mentioned in comments, you have already removed the element and therefore $(this).parent() no longer refers to anything.
Try storing the parent first:
var $parent = $(this).parent(), $selItem = $(this).parents(".selectedItems");
$parent.remove();
if( $selItem.children().length === 0) {
alert("Hello!");
}
Updated Fiddle
change the selector like this,
$(this).parents('.selectedItems').children().length
also you are removing the parent $(this).parent().remove();.
change that too
Demo
You need to first save a count of how many items there are before you remove the item from the DOM. Otherwise the reference to the DOM is lost.
http://jsfiddle.net/thinkingmedia/zXnDa/
$(".selectedItems").on('click', '.deleteItem', function (event) {
var count = $(this).closest(".selectedItems").find(".item").length;
$(this).closest(".item").remove();
if (count == 1) {
alert('hello');
}
});

Better way to Find which element has a specific class from an array of elements

Suppose I have a List like the following
<ul>
<li id="slide-a" class="slide-li active-slide"><a href="#" >A</a></li>
<li id="slide-b" class="slide-li"><a href="#" >B</a></li>
<li id="slide-c" class="slide-li"><a href="#" >C</a></li
</ul>
Now , using Jquery I wanna Find out which Element has the class 'active-class'. One way would to have a nested if statement something like this:
if($("#slide-a").hasClass('active-slide'))
{
active = 'slide-a';
}
else
{
if($("#slide-b").hasClass('active-slide'))
{
active = 'slide-b';
}
else
{
if($("#slide-c").hasClass('active-slide'))
{
active = 'slide-c';
}
}
}
My question is if there exists any way to optimize the code above. Is there a generic way to achieve this such that even if I add 10 more li's in the ul the code just works fine without any modification.
Maybe just
var active = $(".active-slide").attr("id");
Demo
Use Attribute starts with selector and .each(). Try this:
$(document).ready(function(){
$('li[id^=slide]').each(function(){
if($(this).hasClass('active-slide'))
alert($(this).attr('id'));
});
});
DEMO
If you have more than one li with classactive-slide use this:
$(document).ready(function(){
var idVal = [];
$('li[id^=slide]').each(function(){
if($(this).hasClass('active-slide'))
idVal.push($(this).attr('id'));
});
console.log(idVal);
});
DEMO
You could a use jQuery $.each() on the ul to iterate through.
fiddle coming in a second.

Toggle innerHTML

I've seen various examples come close to what I am looking for, but none of it seems to describe it how I exactly want it. I am a beginner to jQuery, so explanations welcome.
I'm looking for this to toggle the innerHTML from - to +. Anyone know of a way to do this, efficiently?
jQuery/JavaScript
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow");
$(".A1").html("+");
});
});
HTML
<div class="A1">-</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
Thank you, anything relating to switching the inside text of an HTML element shall help. =)
How about adding a class that will let you know the expanded/collapsed status?
$(document).ready(function() {
$(".A1").click(function() {
var $this = $(this);
$(".P1").toggle("slow")
$this.toggleClass("expanded");
if ($this.hasClass("expanded")) {
$this.html("-");
} else {
$this.html("+");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="A1 expanded">-</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
Example: http://jsfiddle.net/sGxx4/
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow");
$(".A1").html(($(".A1").html() === "+" ? $(".A1").html("-") : $(".A1").html("+")));
});
});
A bit of explanation: I'm setting $("#A1").html() with the product of the tertiary operator, using it to check for the current value of #A1's text. If it's a +, I set the element's text to -, otherwise, I set it to +.
However, you said "efficiently." To this end, it's important to note that if you're going to use a selector twice or more in the same function, you should store the jQuery object that results from the selector you give in a variable, so you don't have to re-run the selector each time. Here's the code with that modification:
$(document).ready(function() {
$(".A1").click(function() {
var $A1 = $(".A1");
$(".P1").toggle("slow");
$A1.html(($A1.html() === "+" ? $A1.html("-") : $A1.html("+")));
});
});
There's no way to toggle content.
You could check if the $('.P1') is visible, then changing the +/- div according to that.
Something like :
$(document).ready(function() {
$(".A1").click(function() {
$(".P1").toggle("slow", function(){
if($(this).is(':visible'))
$(".A1").html("-")
else
$(".A1").html("+")
});
});
});
Using a callback function (the second argument of the .toggle() method) to do the check will guarantee that you're checking after the animation is complete.
JsFiddle : http://jsfiddle.net/cy8uX/
more shorter version
$(document).ready(function() {
$(".A1").click(function() {
var $self = $(this);
$(".P1").toggle("slow", function ( ) {
$self.html( $self.html() == "-" ? "+" : "-");
});
})
});
Here's a way that uses class names on a parent and CSS rules and doesn't have to change the HTML content and works off a container and classes so you could have multiple ones of these in the same page with only this one piece of code:
HTML:
<div class="container expanded">
<div class="A1">
<span class="minus">-</span>
<span class="plus">+</span>
</div>
<h2 class="H1">Stuff</h2>
<div class="P1">
Stuffy, Stuffy, Stuffed, Stuffen', Stuffing, Good Luck Stuff
</div>
</div>​
CSS:
.expanded .plus {display:none;}
.collapsed .minus {display: none;}
Javascript:
$(document).ready(function() {
$(".A1").click(function() {
$(this).closest(".container")
.toggleClass("expanded collapsed")
.find(".P1").slideToggle("slow");
});
});
​
Working demo: http://jsfiddle.net/jfriend00/MSV4U/

Categories