How to prepend HTML `<li>` to `<ul>` using jQuery? - javascript

I need to append an <li> element to multiple <ul> using a for-loop in jQuery.
Code Snippet:
JQuery:
var lists = $('ul.menu');
for(var i=0; i<lists.length; i++){
var lnk = "<li>All</li>";
lnk = $('<div />').html(lnk).text();
lists[i].prepend(lnk);
}
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Graphics</li>
<li>Videos</li>
<li>Programming</li>
</ul>
<hr>
<ul class="menu">
<li>Our Story</li>
<li>About Us</li>
</ul>
As per code <li> inserts as the proper text, but is been formatted as plain text instead of an <li>.
What am I doing wrong? How to correct my mistakes?

You're calling the raw DOM prepend (which only exists on modern browsers), because lists[i] accesses the raw ul element. You're also just taking the text of what you want to prepend, rather than including any li markup. You probably want to:
Call jQuery's prepend, and
Include the li in what you're prepending
Example:
var lists = $('ul.menu');
for(var i=0; i<lists.length; i++){
var lnk = "<li>All</li>";
lists.eq(i).prepend(lnk);
}
/* No CSS */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Graphics</li>
<li>Videos</li>
<li>Programming</li>
</ul>
<hr>
<ul class="menu">
<li>Our Story</li>
<li>About Us</li>
</ul>

A slightly more jQuery-ish alternative to TJ Crowder's solution...
$('ul.menu').each(function() {
$(this).prepend("<li>All</li>");
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Graphics</li>
<li>Videos</li>
<li>Programming</li>
</ul>
<hr>
<ul class="menu">
<li>Our Story</li>
<li>About Us</li>
</ul>

Related

Selecting anchor child of list item

I'm struggling to select in the DOM the anchor link that is a direct child of my list item "dropdown-nav. It should change the link when the list item is clicked but doesn't. The active class applies perfectly. What am I doing wrong here?
var acc = document.getElementsByClassName("dropdown-nav");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active-hit");
this.find("a").attr("href", "http://www.google.com/");
});
}
<ul>
<li class="dropdown-nav">
<a href="/about">About
<span class="nav-desc">Our company</span>
</a>
<div class="hide-border"></div>
<ul class="second-tier">
<div class="hide-corner"></div>
<li>Our Mission</li>
<li>Our People</li>
<li>Work with us</li>
<li>High Value Manufacturing</li>
</ul>
</li>
</ul>
You included jQuery so you may update your code to simply use jQuery like this:
$(".dropdown-nav").click(function() {
$(this).toggleClass('active-hit');
$(this).find('a').attr("href", "http://www.google.com/");
})
.active-hit {
background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="dropdown-nav">
<a href="/about">About
<span class="nav-desc">Our company</span>
</a>
<div class="hide-border"></div>
<ul class="second-tier">
<div class="hide-corner"></div>
<li>Our Mission</li>
<li>Our People</li>
<li>Work with us</li>
<li>High Value Manufacturing</li>
</ul>
</li>
</ul>
this is not jQuery object. Replace this line:
this.find("a").attr("href", "http://www.google.com/");
With this (this will change href of first link, if you need to change all of them, then iterate):
this.getElementsByTagName('a')[0].setAttribute('href', 'http://www.google.com/');
If you have included jQuery, you can do this too:
$(this).find("a").attr("href", "http://www.google.com/");

How can I change span text inside another span?

I am trying to make a collapsible list that changes from a '+' to a '-' and back depending upon whether the list is collapsed or expanded. I can get to the text using this statement:
$(this).children().eq(i).children('span')[0].firstChild.outerText;
But I cannot figure out how to change the value. There's probably a more elegant solution that a JQuery Guru can show me. Here is my JSFiddle.
This answer is the closest answer I could find to my question but I don't know how to implement it or even if there is a better way.
This can be simplified quite a bit. Rather than trying to match index, just use jQuery's find() method to target descendants:
$('#test > li').click(function() {
var $symbol = $(this).find('.symbol');
$(this).find('ul').slideToggle('fast');
if ($symbol.text() === ' +') {
$symbol.text(' -');
} else {
$symbol.text(' +');
}
});
.hideUnorderedList {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="test">
<li id="first">
<span class="Collapsable"><span class="symbol"> +</span>First One</span>
<ul id="myfirstlist" class="hideUnorderedList">
<li>Something to do</li>
<li>Something else to do</li>
</ul>
</li>
<li id="second">
<span class="Collapsable"><span class="symbol"> +</span>Second One</span>
<ul id="mysecondlist" class="hideUnorderedList">
<li>Second thing to do</li>
<li>Second other thing to do</li>
</ul>
</li>
</ul>
</div>
// Make your code clean and readable!
// Don't target #test. Go directly for your "title/heading" elements ("buttons")
$(".Collapsable").on("click", function() {
// Who is my +/- icon element?
var $ico = $(this).find(".symbol");
// Traverse up to LI and than back down to find my UL sub list:
var $subList = $(this).closest("li").find("> ul");
// Realize the current collapsed/expanded state
var isSubListHidden = $subList.is(":hidden");
// OK, time to rock!
// Change teh text +/-
$ico.text(isSubListHidden ? "-" : "+");
// Toggle sub lists:
$subList.stop().slideToggle();
});
.hideUnorderedList {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="test">
<li id="first">
<span class="Collapsable"><span class="symbol">+</span>First One</span>
<ul id="myfirstlist" class="hideUnorderedList">
<li>Something to do</li>
<li>Something else to do</li>
</ul>
</li>
<li id="second">
<span class="Collapsable"><span class="symbol">+</span>Second One</span>
<ul id="mysecondlist" class="hideUnorderedList">
<li>Second thing to do</li>
<li>Second other thing to do</li>
</ul>
</li>
</ul>
</div>

How to sort list items based on id attribute using jquery?

Hello so I have this problem, I use magento and my I can't find a place how to switch my tabs in position so I thought JQuery could come in hand. So this is what i have as an example
<li id="tab-4">
<li id="tab-3">
<li id="tab-2">
<li id="tab-1">
And i need to make it
<li id="tab-1">
<li id="tab-2">
<li id="tab-3">
<li id="tab-4">
Is there a fast way to do it? Or I have to do it one by one?
I guess you have an <ul> around you <li>
ul = $('ul'); // your parent ul element
ul.children().each(function(_,li){ul.prepend(li)})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="tab-4">4</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
<li id="tab-1">1</li>
</ul>
Pure JS solution.
var a = document.getElementsByTagName('li');
var b = document.getElementById('list');
var arr = [];
Array.from(a).forEach(v => arr.push(v));
arr.reverse().forEach(v => b.append(v));
<ul id='list'>
<li id="tab-4">4</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
<li id="tab-1">1</li>
</ul>
Also, for a sollution working (actually sorting) regardless of the initial order you can use sort() and append like this:
$("ul li").sort(function(a,b){
if(a.id.substring(4, 5) < b.id.substring(4, 5)) {
return -1;
} else {
return 1;
}
}).each(function() { $('ul').append(this);});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id="tab-4">4</li>
<li id="tab-1">1</li>
<li id="tab-3">3</li>
<li id="tab-2">2</li>
</ul>
$(".list > li").detach().sort(function(a, b) {
return +a.id.replace("tab-","") - b.id.replace("tab-","") ;
}).appendTo("ul.list");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li id="tab-3">3
<li id="tab-4">4
<li id="tab-2">2
<li id="tab-1">1
</ul>
If your HTML code like this you can write your code using detach and a single appendTo like this.
More about detach(): https://www.w3schools.com/jquery/html_detach.asp

Want jquery to replace same <li> and all element insie ul

I want jquery to include <li> and all other tags inside <ul class="visib-1"></ul> to <ul class="visib-2"></ul> without writing li,a href="" tags again. Is there have any solution?Is it possible to capture all elements from one UL and transfer to other UL?
From:
<ul class="visib-1">
<li>Home</li>
<li>Properties</li>
<li>Blog</li>
<li>Start Now</li>
</ul>
To:
<ul visib-1>
?
</ul>
If all you want is to move from one <ul> to another:
$('#first-ul-id li').appendTo('#second-ul-id');
If you want to copy use clone()
$('#first-ul-id li').clone().appendTo('#second-ul-id');
Here is the solution. Check the code below:
This code will also copy the event handlers attached.
var cloneOfOld = $('[data-status="old"]').clone(true);
cloneOfOld.attr('data-status','new');
var newUl = $('[data-status="new"]');
newUl.replaceWith(cloneOfOld);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul data-status="old"><li>Home</li>
<li>Properties</li>
<li>Blog</li>
<li>Start Now</li>
</ul>
<ul data-status="new">
</ul>

javascript horizontal menu click to open

Trying to make javascript horizontal menu, but can't get second button to open its own items, (when i click the second button it opens the items that are for the first button) here is current code:
JavaScript:
$(document).ready(function() {
$(".menu-button,.menu-button1").click(function() {
$(".menu-bar").toggleClass("open");
});
})
HTML:
<ul class="menu">
<li title="home">menu</li>
<li title="pencil">pencil</li>
<li title="about">about</li>
</ul>
<ul class="menu-bar">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
<ul class="menu-bar">
<li>Menu1</li>
<li>About</li>
</ul>
Before I start my answer, let me explain jQuery a bit.
$(".menu-button,.menu-button1").click(function() {
$(".menu-bar").toggleClass("open");
});
This broken down:
$(".menu-button,.menu-button1").click(function() { -> When any item with class menu-button OR class menu-button1 is clicked
$(".menu-bar").toggleClass("open"); ->Toggle the "open" class for all elements in your page with class menu-bar.
Since you call all the menus instead of the specific one you want, it opens both of them.
So, be more specific by - for starters - using IDs, or unique/identifying classes:
JS:
$(document).ready(function() {
$(".menu-button.home").click(function() {
$(".menu-bar.home").toggleClass("open");
});
$(".menu-button.pencil").click(function() {
$(".menu-bar.pencil").toggleClass("open");
});
})
HTML:
<ul class="menu">
<li title="home">menu</li>
<li title="pencil">pencil</li>
<li title="about">about</li>
</ul>
<ul class="menu-bar home">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
<ul class="menu-bar pencil">
<li>Menu1</li>
<li>About</li>
</ul>
I agree with M.Doye's comment about using .each (but sorry, I can't answer directly).
I want to add that, it will be much easier with that kind of HTML structure I think:
<ul class="menu">
<li title="home">
Show Menu 1
<ul class="menu-bar">
<li>Menu1
</li>
</ul>
</li>
<li title="pencil">
Show Menu 2
<ul class="menu-bar">
<li>Menu2
</li>
</ul>
</li>
</ul>
The, click on the link and use .next() or .siblings or closest... to show the right ul.
But of course you'll have to rewrite you CSS :)
Here is updated code
$(document).ready(function () {
$(".menu-button,.menu-button1").click(function () {
$(this).siblings(".menu-bar").toggleClass("open");
})
})
<ul class="menu">
<li title="home">menu
<ul class="menu-bar">
<li>Menu1</li>
<li>About</li>
</ul>
</li>
<li title="pencil">pencil
<ul class="menu-bar">
<li>Menu0</li>
<li>Home2000</li>
<li>About</li>
<li>Parent</li>
<li>About</li>
</ul>
</li>
</ul>
here is a jsfiddle

Categories