create list of each siblings children - javascript

I have multiple sections with multiple sub-sections. Each section should have a list of all sub-section h3-headings within this section. Given this HTML:
<div class="allwrap">
<div class="main-section" id="m1">
<h2>Main-1-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-1 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m1-s1">
<h3>Main-1-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m1-s2">
<h3>Main-1-Sub-2-Headline</h3>
</div>
</div>
<div class="main-section" id="main-2">
<h2>Main-2-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-2 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m2-s1">
<h3>Main-2-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m2-s2">
<h3>Main-2-Sub-2-Headline</h3>
</div>
</div>
</div>
So I iterate over each sections subsection H3 and have an array of ALL h3-headings now which is not what i want to accomplish:
var myList = [];
$('.main-section .sub-section').each(function(){
myList.push($(this).find('h3').text());
});
$.each(myList, function(){
var li = $('<li/>').appendTo('.sub-sections-list');
$('<a/>').attr('href', '#').text(this).appendTo(li);
});
How can i make it so that not all h3-headings of all sections are in the list but only the headings of the respective parent section? The result should look like this:
Main-1-Headline (begin of Main-section-1)
Main-1-Sub-1-Headline
Main-1-Sub-2-Headline
Main-1-Sub-1-Headline (begin of sub-section-1)
Some content here (not in above HTML for keeping it simple)
Main-1-Sub-2-Headline (begin of sub-section-2)
Some content here (not in above HTML for keeping it simple)
Main-2-Headline (begin of Main-section-2)
Main-2-Sub-1-Headline
Main-2-Sub-2-Headline
Main-2-Sub-1-Headline (begin of sub-section-1)
Some content here (not in above HTML for keeping it simple)
Main-2-Sub-2-Headline (begin of sub-section-2)
Some content here (not in above HTML for keeping it simple)

I think you want this.
Updated short way demo
$('.main-section h3').each(function(){
$(this).parent().prevAll(".sub-sections-list").append('<li>'+$(this).text()+'</li>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="allwrap">
<div class="main-section" id="m1">
<h2>Main-1-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-1 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m1-s1">
<h3>Main-1-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m1-s2">
<h3>Main-1-Sub-2-Headline</h3>
</div>
</div>
<div class="main-section" id="main-2">
<h2>Main-2-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-2 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m2-s1">
<h3>Main-2-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m2-s2">
<h3>Main-2-Sub-2-Headline</h3>
</div>
</div>
</div>
Old way
$('.main-section').each(function() {
var myList = [];
$(this).find("h3").each(function() {
myList.push($(this).text());
});
$subSectionList = $(this).find('.sub-sections-list');
$.each(myList, function() {
var li = $('<li/>').appendTo($subSectionList);
$('<a/>').attr('href', '#').text(this).appendTo(li);
});
});

Something like this (optimized version):
$('.main-section').each(function(){
var ul = $(this).find('.sub-sections-list');
$(this).find('h3').each(function(){
ul.append('<li>'+$(this).text()+'</li>');
});
});
Example: https://jsbin.com/gefupivoji/edit?html,js,output

Related

Count parent child child nodes

So I want to know how do I get count of parent child child childs for example:
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.childNodes.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
<ul>
</div>
</div>
And now I want count how many <ul class="child3-child"> has child elements in this case it has only 1 li.
Use children instead of childNodes. The former includes HTML Elements while the latter includes text nodes.
Close your </ul> tag properly or else the borwser will think it's opening a nested element.
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.children.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
</ul> <!--- This wasn't properly closed -->
</div>
</div>

jQuery slider index

I'm trying to duplicate the text inside the <h1> tag in the .slider-item divs to the anchor tags in the .bx-pager div. For example, the anchor in the first .bx-pager-item should have the text of the h1 in the first .slider-item div. Then the anchor tag in the second .bx-pager-item should have the text of the <h1> in the second .slider-item div. Is there something wrong with my jQuery code that makes it not do what I want?
My jQuery code:
$(window).load(function(){
$("#pagination .bx-pager-item").each(function(){
var whichPos = $(this).index();
var whichSlide = $('.slider-item').index(whichPos).find('h1').text();
$(this).find('a').text(whichSlide);
});
});
The pagination:
<div id="pagination">
<div class="bx-pager-item"></div>
<div class="bx-pager-item"></div>
<div class="bx-pager-item"></div>
</div>
The slider structure is:
<div class="bxslider">
<div class="slider-item">
<h1>Header</h1>
</div>
<div class="slider-item">
<h1>Header 2</h1>
</div>
<div class="slider-item">
<h1>Header 3</h1>
</div>
</div>
Change:
var whichSlide = $('.slider-item').index(whichPos).find('h1').text();
to:
var whichSlide = $('.slider-item').eq(whichPos).find('h1').text();
index does not get the nth element, it returns a number.
CodePen: http://codepen.io/theblindprophet/pen/JKLbXw

Find Child elements in a div and append them to another Child element using javascript

I want the elements to be appended to another elements - they have to
be found in a div class that have id="parent".
the code must be only in clean javascript. The problem is, why i cant use just append - children append only for 1 element(first block) so need a loop that will get every element(2) to append to the (1) element.
<!-- FirstBlock -->
<div id="parent">
<div id="firstElement">
</div>
<div id="secondElement">
</div>
</div>
I want it to look like this
<!-- FirstBlock -->
<div id="parent">
<div id="firstElement">
<div id="secondElement">
</div>
</div>
</div>
Here is the code i tried:
function getElement() {
var firstElement = document.getElementById('firstElement');
var secondElement = document.getElementById('secondElement');
var parent = document.getgetElementById('parent').children;
for(var i = 0; i < parent.length; i++){
for(firstElement in parent[i]){
if(!(secondElement in firstElement){
firstElement.appendChild(secondElement);
});
};
};
Fiddle
With the ID's being the same, you need to use a class attribute instead or change the ID for each of those elements. Here's an example of how you could achieve your result(CSS for visual example).
function getElement() {
var parents = document.getElementsByClassName('parent'),
parentsLength = parents.length;
while (parentsLength--){
var firstElements = parents[parentsLength].getElementsByClassName('firstElement'),
firstElementsLength = firstElements.length,
secondElements = parents[parentsLength].getElementsByClassName('secondElement');
while(firstElementsLength--) {
var secondElementsLength = secondElements.length;
while(secondElementsLength--) {
firstElements[firstElementsLength].appendChild(secondElements[secondElementsLength]);
}
}
};
}
getElement();
.firstElement {
height: 50px;
border: 1px solid #000;
}
.secondElement {
background-color: #aaa;
}
<!-- FirstBlock -->
<div class="parent">
<div class="firstElement">
dddd
</div>
<div class="secondElement">
aaa
</div>
</div>
<!-- SecondBlock -->
<div class="parent">
<div class="firstElement">
firstElement
</div>
<div class="secondElement">
secondElement
</div>
</div>
<!-- ThirdBlock -->
<div class="parent">
<div class="firstElement">
firstElement
</div>
<div class="secondElement">
secondElement
</div>
</div>
I want it look like this
<!-- FirstBlock -->
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
<!-- SecondBlock -->
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
<!-- ThirdBlock -->
<div>
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
A quick rundown of the JavaScript..
We're getting each element with the parent class and setting a variable to the length of that object.
The while loop is running through each of those divs and getting the divs inside that contain the firstElement and secondElement classes.
Then more loops take each element with the class secondElement and insert them into the elements with the class firstElement.
At the end of it, for every parent div, any divs with a class of secondElement will be inserted into every div with a class of firstElement inside of that parent div.
Here is the fiddle that I went off of for modifications. Hope this helps!
Change your HTML code to have classes, instead of id's. There can't be more than one element with the same id.
<div class="parent">
<div class="firstElement">
</div>
<div class="secondElement">
</div>
</div>
Then use the following JavaScript:
var parents = document.getElementsByClassName("parent");
for(i = 0; i < parents.length; i++){
var current = parents[i];
var firstElement = current.getElementsByClassName("firstElement")[0];
var secondElement = current.getElementsByClassName("secondElement")[0];
firstElement.appendChild(secondElement);
current.removeChild(firstElement);
}

Javascript foreach array key values, output to html

How do I loop thru array keys to output their values to HTML?
The layout I'm working with is a thumbnail grid, 3 columns by 2 rows. Each thumbnail has a caption below it. Selecting any of the thumbnails opens up a hidden container which is also a grid of 3 columns and 2 rows. Within that hidden container many of the images and captions are going to be identical so rather than have a whole bunch of duplicate HTML I figured I could just store each in an array and reference the values that each is associated with. I'm just stuck on how to create the loop at the moment.
var img=[
'image01.jpg','image02.jpg','image03.jpg','image04.jpg'
]
var details=[
'aaaaaa','bbbbbb','cccccc','dddddd'
];
$( "#yin" ).click(function() {
var img = [0,2];
var details = [0,1];
$(step).each(function() {
document.getElementById("img").innerHTML();
});
$(imgs).each(function() {
document.getElementById("img").innerHTML();
});
});
<div class="container">
<ul class="row-fluid">
<li class="span4" id="yin">
<div class="row-fluid">
<img src="yin.jpg" />
<h3>Yin</h3>
</div>
</li>
<li class="span4" id="yang">
<div class="row-fluid">
<img src="yang.jpg" />
<h3>Yang</h3>
</div>
</li>
</ul>
<div class="row-fluid">
<div class="span12">
<div class="show-details details">
<div class="detail-content">
<div id="img">
<!-- Loop (for yin would be image01, and image03) -->
</div>
<div id="details">
<!-- Loop (for yin would be 'aaaaaa','bbbbbb') -->
</div>
</div>
</div>
</div>
</div>
</div>
There's an issue with that code before you get into looping, the img and details variables are being re-declared inside your click function. What are they intended to be? From the comments in your code they seem to be specifying which indices of the array to use.
var images = ['image01.jpg','image02.jpg','image03.jpg','image04.jpg'];
var details = ['aaaaaa','bbbbbb','cccccc','dddddd'];
$( "#yin" ).click(function() {
var imgIndices = [0,2];
var detailIndices = [0,1];
$("#img").html("");
$("#details").html("");
$(imgIndices).each(function(i, o) {
$("#img").append("<img src=\"" + images[o] + "\"/>");
});
$(detailIndices).each(function(i, o) {
$("#details").append("<p>" + details[o] + "</p>");
});
});
<div class="container">
<ul class="row-fluid">
<li class="span4" id="yin">
<div class="row-fluid">
<img src="yin.jpg" />
<h3>Yin</h3>
</div>
</li>
<li class="span4" id="yang">
<div class="row-fluid">
<img src="yang.jpg" />
<h3>Yang</h3>
</div>
</li>
</ul>
<div class="row-fluid">
<div class="span12">
<div class="show-details details">
<div class="detail-content">
<div id="img">
<!-- Loop (for yin would be image01, and image03) -->
</div>
<div id="details">
<!-- Loop (for yin would be 'aaaaaa','bbbbbb') -->
</div>
</div>
</div>
</div>
</div>
</div>
I would take the click function out to a named function though and just pass in the arrays.

JQuery order div by value and skip if value is zero

I've done my ordering in my code but instead of reloading the whole json result, I want a client side reorder for my divs.
My C# code for ordering is:
.OrderBy(p=> p.order == 0? int.MaxValue : p.order);
This give me result like
1
2
3
4
0
0
0
My Html schema is like
<div class="item" data-sort="0" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
<div class="item" data-sort="2" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
<div class="item" data-sort="0" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
How can I reorder these divs so that the 2nd one become first and those with 0 data will be last upon reordering.
Take a look at the jQuery plugin TinySort if you're using jQuery. Here is an example of its use:
$(".item").tsort({ attr: 'data-sort',order:'desc'});
I think if you can output 0 or -1 instead of null to the data-sort attribute it should put those items at the end.
You can also do like this:
Put all your divs inside a parent div
<div id="parentDiv">
..
</div>
Then you can sort like this
$(function(){
function sort_comp(a, b){
var k1 = parseInt($(a).attr("data-sort"),10);
if(k1 === 0) k1 = Number.MAX_VALUE;
var k2 = parseInt($(b).attr("data-sort"),10);
if(k2 === 0) k2 = Number.MAX_VALUE;
return (k1-k2);
}
var arr = $.makeArray($("#parentDiv > .item"));
arr.sort(sort_comp);
$("#parentDiv > .item").remove();
$(arr).each(function(){
$("#parentDiv").append($(this));
});
});

Categories