Chaining jquery append - javascript

I'm trying to figure out how I can chain multiple append into my markup. Basically after appending an element, I would like the next element to append it to the first appended element. I hope what I'm saying makes sense.
If you take a look at my code, I just appended the element <ul class="menu" /> into the element #footer .research-centers-menu .research.
Then on the next code I'm trying to insert/append the variable centers to the <ul class="menu" />
The current output right now doesn't insert the element but places it outside instead. Apologies for my bad english and explanation
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters),
centers = centersList.slice(0);
var research = $('#footer .research-centers-menu .research').append('<ul class="menu" />');
$(research).append(centers);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<ul>
<li>item one</li>
<li>item two</li>
</ul>
</li>
</ul>
<div id="footer">
this is a footer
<div class="research-centers-menu">
<div class="research">
</div>
</div>
</div>

The cause of your appending issue is because append() returns the original element, not the appended element.
To make your code work you could invert the logic so that you create the new ul, then use appendTo(). This will retain the reference required to append the li. Try this:
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters);
var $research = $('#footer .research-centers-menu .research');
var $ul = $('<ul class="menu" />').appendTo($research);
$ul.append(centersList);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<ul>
<li>item one</li>
<li>item two</li>
</ul>
</li>
</ul>
<div id="footer">
this is a footer
<div class="research-centers-menu">
<div class="research"></div>
</div>
</div>

try to append like this.
var researchCenters = $('a[href$="/items"]').next().clone(),
centersList = $('li', researchCenters),
centers = centersList.slice(0);
var research = $('#footer .research-centers-menu .research')
var ul =$('<ul class="menu" />').append(centers);
research.append(ul);

Related

Jquery combining text from parent li elements on click to get path

I am struggling with jquery a little. I have an unordered list that looks like this.
<ul>
<li class="folder">Folder: Test</li>
<ul>
<li class="folder">Folder: Archive</li>
<ul>
<li class="file">
<div class="filename">HelloWorld.docx</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docx</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</ul>
</ul>
Which looks like this
Folder: Test
Folder : Archive
HelloWorld.docx
11.79kiB
2021-01-12 09:31:34
HelloWorld1.docx
12.79kiB
2021-01-11 09:31:34
When I click on any of the li's with the class of "file" I want to look back and work out what the path structure is by finding the parent li's that have the class "folder".
I have tried various combinations but cannot get it
This is what I am working with at the moment
$(document.body).on('click',"li.file",function (e) {
console.log("clicked");
$(this).parents("li.folder").each(function() {
console.log($(this).text());
});
});
Ultimately i want to get back a full path with the parent folder and the filename in a variable.
e.g. pathtofile = /Test/Archive/HelloWorld.docx
Here is a jsfiddle https://jsfiddle.net/e5d7bcyz/
Thanks
Before approaching your question you first need to correct the HTML. ul elements cannot be children of other ul elements. You need to wrap the ul within their associated li.
You will also need to wrap the folder names in another element, such as a span, in order for the text to be easily retrievable. This would be possible with your current HTML by trawling through text nodes, however that is messy code to write and very brittle. A simple HTML change is the best approach there.
Finally, you can loop through the parent li elements of the clicked .file and reverse their order to get the path in the right format. From there you can append the filename of the selected file. Try this:
$.fn.reverse = [].reverse;
$(document).on('click', "li.file", function(e) {
let $file = $(this);
let $path = $file.parent().parents('li').reverse();
let path = $path.map((i, el) => $(el).children('span').text().trim()).get();
path.push($file.children('.filename').text().trim());
console.log(path.join('/'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="folder">
<span>Test</span>
<ul>
<li class="folder">
<span>Archive</span>
<ul>
<li class="file">
<div class="filename">HelloWorld.docs</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docs</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Well, the LI you're looking for are not really the parents as they're not wrapping the current li.file element.
<ul>
<li class="folder">Folder: Archive</li> // You close the LI tag. So it's not a parent of the rest of the code.
<ul>
<li class="file">
Try to wrap the rest of the code with the LI tag:
<ul>
<li class="folder">Folder: Test
<ul>
<li class="folder">Folder: Archive
<ul>
<li class="file">
<div class="filename">HelloWorld.docx</div>
<div class="size">11.79kiB</div>
<div class="date">2021-01-12 09:31:34</div>
</li>
<li class="file">
<div class="filename">HelloWorld1.docx</div>
<div class="size">12.79kiB</div>
<div class="date">2021-01-11 09:31:34</div>
</li>
</ul>
</li> //closing the second parent: Folder: Archive
</ul>
</li> //closing the first parent: Folder: test
</ul>
As far as I know it's valid HTML code.
And then those li.folder elements would be actually parents.

how to get text inside a li element on click in pure javascript

The folliwing code is working ONLY with the getElementById method, but i need it to works even in the case there is not an ID on element.
My HTML is:
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>
My JS is:
<script>
var el = document.getElementById("pid");
el.onclick = function what_to_do(){
var theText = this.innerHTML;
alert(theText);
</script>
So i need to get the text in the deepest nested LI element that has no ID when the user clicks over it.
usually with jquery i can make $("#container ul li ul li").on("click, ...
but i am trying to work with pure javascript (vanilla js).
Is there anyone else that can help me?
Thanks in advance
You can use document.querySelectorAll().
Note: You can't just set event to the document.querySelectorAll() like jQuery you need to loops through whole array
const items = document.querySelectorAll('li > ul > li');
items.forEach(item => {
item.addEventListener('click',(e)=>{
console.log(e.target.textContent);
}
)
})
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>
use document.querySelector
var el = document.querySelector("#container > .menu > li > .submenu > li");
el.onclick = function what_to_do(){
var theText = this.innerHTML;
alert(theText);
}
<div id="container">
<ul class="menu">
<li>
<ul class="submenu">
<li>text i have to get</li>
</ul>
</li>
</ul>
</div>

Add extra pair of UL using JavaScript/JQuery

I have done coding the first part HTML then JavaScript/JQuery. Now I want to surround the final common list with a UL need to be done using JavaScript/JQuery. So the final common list will be surrounded by two UL instead of one. Eg
Final Outcome
<ul id="CommonLister">
<ul> <!--Need to add this-->
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul><!--Need to add this-->
</ul>
Current Code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="listOne">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="listTwo">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="CommonLister">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul>
</div>
$(function() {
$('#run-code').on('click', function(e) {
e.preventDefault();
//What were you doing? nope.
var currentItems = {}; //Blank object
var $mergeColumn = $('#CommonLister'); //Common list reference
$('.columnItem').each(function(i, el) {
var $el = $(el); //Notation I use to differentiate between the regular HTML Element and jQuery element
if (!currentItems.hasOwnProperty($el.html())) {
//Has this name come up before? if not, create it.
currentItems[$el.html()] = []; //Make it equal to a brand spanking new array
}
currentItems[$el.html()].push(el);
//Add the item to the array
});
$.each(currentItems, function(name, data) {
//Loop through each name. We don't actually use the name variable because we don't care what someone's name is
if (data.length > 1) {
//Do we have more than 1 element in our array? time to move some stuff
$.each(data, function(i, el) {
var $el = $(el); //See note above
if (i == 0) {
//If this is the first element, let's just go ahead and move it to the merge column ul
$el.appendTo($mergeColumn);
} else {
$el.remove(); //Otherwise, we've already got this element so delete this one.
} //end if/else
}); //end $.each(data)
} //end if data.length >1
}); //end $.each(currentItems)
}); //end $.on()
}); //end $(
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run-code" class="btn btn-success">Click Me</button>
<h4>List 1</h4>
<ul id="listOne">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>List 2</h4>
<ul id="listTwo">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>Common List</h4>
<ul id="CommonLister">
<!--Extra ul will be added here-->
</ul>
It's invalid nesting a ul directly in a ul like this but if you have to, you could use jquery wrapAll:
$( "li" ).wrapAll( "<ul></ul>" );
See fiddle: https://jsfiddle.net/9xLt6d9f/
I agree with charlietfl that it seems strange to do it this way. However, to answer your question, the best way to force this improperly formatted HTML code would be hardcode it into your original file. Try the following code for the end of your file:
<h4>Common List</h4>
<ul id="CommonLister">
<ul id="CommonListerSub">
<!--Extra ul will be added here-->
</ul>
</ul>
Then, simply change one line of your code:
var $mergeColumn = $('#CommonListerSub'); //Common list reference
This will force it to list the list items under the nested ul tags.
I hope this is an acceptable solution. If for some reason it doesn't work, please comment as to what additional limitations you have, and perhaps share the link of the page that is giving you the required template or format specifications.

Javascript post filtering system not functioning

I'm trying to create a simple filtering systemt that would hide posts that do not have the same id as the li's under the navig class. To achieve this I am looping through all .article li's and checking what's their id.
Example:
click on li with id="health"
Article 2 disappears
Thank you!
HTML:
<ul class="navig">
<li id="health">Health</li>
<li id="ASD">ASD</li>
</ul>
<br>
<ul class="article">
<li id="health">Article 1</li> <br>
<li id="ASD">Article 2</li> <br>
<li id="health">Article 3</li>
</ul>
Javascript:
$('.navig li').onclick(function () {
$id = this.id;
$('.article li').each(function() {
if ($id != this.id) {
$('.article li').hide();
}
});
});
The fundamental problem is your HTML is invalid. You can't use the same id value on more than one element. Separately, you've used onclick where you would want to use click.
I'd probably use a data-article-id attribute on the navigation li instead, like this:
For example: Live copy (source)
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<meta charset="utf-8">
<title>Testing</title>
</head>
<body>
<ul class="navig">
<li data-article-id="health">Health</li>
<li data-article-id="ASD">ASD</li>
</ul>
<br>
<ul class="article">
<li id="health">Health Article</li>
<li id="ASD">ASD Article</li>
</ul>
<script>
$('.navig li').click(function () {
var articleId = $(this).attr("data-article-id");
alert(articleId);
var articles = $(".article li");
articles.not("#" + articleId).hide();
$("#" + articleId).show();
});
</script>
</body>
</html>
You'll want to do something to hide the articles (or show a default one) when the page loads, etc.; I'll leave that as an exercise for you. :-)
Side note: br elements cannot be children of ul elements, I've removed the ones from the articles list.
$('.navig li').onclick(function () { <-- not valid jquery
There is no onclick method in jQuery...there is .click(function(){}) or on("click", function(){})
second porblem, ids need to be singular. They can not be repeated. Use a data attribute [and br's can not be children of ul]
<ul class="navig">
<li id="health">Health</li>
<li id="ASD">ASD</li>
</ul>
<br>
<ul class="article">
<li data-id="health">Article 1</li>
<li data-id="ASD">Article 2</li>
<li data-id="health">Article 3</li>
</ul>
and script
$('.navig li').on("click", function() {
var id = this.id;
$(".article li").hide().filter('[data-id="' + id + '"]').show();
});
JSFiddle: http://jsfiddle.net/q8SCF/

help building a section nav menu with jquery

I could really use some help with what I have a feeling will be some pretty basic jquery, but I'm stuck all the same.
I have an unknown (dynamically generated) number of divs in my html each with a class of "page".
What I want to do is add an id to each div.page, and then fill a ul with an id of menu with li for each div.page containing an anchor with a href value of #page_n
(ie the id value of its corresponding div)
I want my output to look like this:
<div class="page" id="page_1">
...content...
</div>
<div class="page" id="page_2">
...content...
</div>
.....
<div class="page" id="page_n">
...content...
</div>
<ul #menu>
<li>Page 1</li>
<li>Page 2</li>
.....
<li>Page n</li>
</ul>
I'm adding the id's okay with:
$('li.page').each(function(index){$(this).attr("id", "page_" + (index+1));
});
But I'm struggling with the second part of my problem. I know this is probably kinda basic, but I'm just starting out....
Any help gratefully received... thanks in advance...
If your HTML initially looks like this:
<div class='page'>...</div>
<div class='page'>...</div>
<div class='page'>...</div>
<ul id='menu'></ul>
This jQuery code:
$(document).ready(function() {
$('div.page').each(function(i) {
var x = i+1;
var id = 'page_' + x;
$(this).attr('id', id);
var li = $('<li/>').append(
$('<a/>').attr('href', '#' + id).html('Page ' + x)
);
$('#menu').append(li);
});
});
Will make your HTML look like this:
<div class='page' id='page_1'>...</div>
<div class='page' id='page_2'>...</div>
<div class='page' id='page_3'>...</div>
<ul id='menu'>
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>

Categories

Resources