jquery select div index - javascript

let's assume I have the following divs
<div class="category"></div>
<div class="item"></div>
<div class="item"></div>
<div class="category"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="category"></div>
<div class="item"></div>
I would like to access a specific div with class "category".
I know I can use this to get the first:
$(".category").first()
But what if I want to get the 2nd or the 3rd? etc..?

You can use eq() to select an element using index.
Reduce the set of matched elements to the one at the specified index.
$('.category').eq(2) // 3rd element
Note: The index starts from zero.
Demo
$('.category').eq(2).css('background', 'green');
.category {
background: red;
width: 100px;
height: 100px;
margin: 10px;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class="category">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="category">D</div>
<div class="item">E</div>
<div class="item">F</div>
<div class="item">G</div>
<div class="item">H</div>
<div class="category">I</div>
<div class="item">J</div>

Related

Get index of element among siblings ignoring sibling with specific child

I have a specific use case I can't seem to find an answer to. Given the DOM elements below:
<div class="wrapper">
<div class="item"></div>
<div class="item">
<div class="foo"></div>
</div>
<div class="item">
<div class="bar"></div>
</div>
<div class="item"></div>
<div class="item selected"></div>
<div class="item"></div>
</div>
I need to find the index of the .selected element in regard to it's siblings. But I need to ignore any siblings that have the .foo child element (it will only ever be the direct child).
So typically to find the index of .item .selected you could use $(".item.selected").index() which gives 4, but since one item before it has a .foo child the correct answer is 3.
I thought, the best way to go about it was to grab all the siblings before the selected element (since siblings after it wouldn't shift it's index) and then count how many have a .foo child, and subtract that number from the selected index, so 4-1=3. I tried to do that like this:
var selectedIndex = $(".item.selected").index();
var fooCount = $(".item.selected").prevAll('.item > .foo').length;
var finalIndex = selectedIndex - fooCount;
The problem is, fooCount is coming up 0 instead of 3.
You can simply use .filter() and remove the preceding elements that have a given child.
const selected = $('.selected');
const foos = selected.prevAll().filter(function() {
return !($(this).find('.foo').length);
});
console.log(selected.index(), foos.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="item"></div>
<div class="item">
<div class="foo"></div>
</div>
<div class="item">
<div class="bar"></div>
</div>
<div class="item"></div>
<div class="item selected"></div>
<div class="item"></div>
</div>
Use this selector ".item:not(:has(.foo))" and then loop to find the specific index.
var index = $(".item:not(:has(.foo))")
.toArray()
.findIndex(function(item) {
return $(item).hasClass('selected');
});
console.log(index);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="item"></div>
<div class="item">
<div class="foo"></div>
</div>
<div class="item">
<div class="bar"></div>
</div>
<div class="item"></div>
<div class="item selected"></div>
<div class="item"></div>
</div>
You were close.
Change:
var fooCount = $(".item.selected").prevAll('.item > .foo').length;
… to:
var fooCount = $(".item.selected").prevAll('.item:has(.foo)').length;
Otherwise, you're looking for a sibling with class .foo, when you actually want a sibling that has a child with class .foo.
Snippet:
var selectedIndex = $(".item.selected").index();
var fooCount = $(".item.selected").prevAll('.item:has(.foo)').length;
var finalIndex = selectedIndex - fooCount;
console.log(finalIndex);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="item"></div>
<div class="item">
<div class="foo"></div>
</div>
<div class="item">
<div class="bar"></div>
</div>
<div class="item"></div>
<div class="item selected"></div>
<div class="item"></div>
</div>
You can combine:
:not(): selects all elements that do not match the given selector.
:has(): reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.
:index(element): where element is the DOM element or first element within the jQuery object to look for.
Hence, you can change your code:
var selectedIndex = $(".item.selected").index();
to:
var selectedIndex = $('.item:not(:has(.foo))').index($('.item.selected'));
var selectedIndex = $('.item:not(:has(.foo))').index($('.item.selected'));
console.log(selectedIndex );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="item"></div>
<div class="item">
<div class="foo"></div>
</div>
<div class="item">
<div class="bar"></div>
</div>
<div class="item"></div>
<div class="item selected"></div>
<div class="item"></div>
</div>

Fill divs with content from hidden directory

I have a hidden directory (.directory) with several divs (.content) and different content in it.
Now on pageload, I want to randomly pick a div (.content) from the directory and place it in the lower, visible divs (.box).
The hidden directory has more divs (.content) than should be shown at the end in the visible divs (.box). For example, I have 20 hidden content divs, but just randomly 3 should be shown.
So my solution would be, that JS counts on pageload, how much divs named ".box" and then randomly pick the counted amount of divs named ".content" from the directory and place in the divs named ".box". Would that be the right way?
But I really have no idea, how to do that :D
I have prepared a fiddle: https://jsfiddle.net/m5sqwrpg/4/
Here is the HTML
<div class="directory">
<div class="content">
<div class="headline">Headline A</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline B</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline C</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline D</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline E</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline F</div>
<div class="text">Some kind of Content</div>
</div>
</div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
And the CSS:
.directory {
display: none;
}
.content {
margin-bottom: 20px;
border-bottom: 1px solid black;
padding-bottom: 10px;
}
Thank you so much!
Here is something that should get you started:
$(document).ready(function(){
$(".box").each(function(){
var contentDivs = $(".directory .content");
var contentToPick = Math.floor(Math.random()*(contentDivs.length));
$(contentDivs[contentToPick]).appendTo($(this));
});
});
.directory {
display: none;
}
.content {
margin-bottom: 20px;
border-bottom: 1px solid black;
padding-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.0.min.js"></script>
<div class="directory">
<div class="content">
<div class="headline">Headline A</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline B</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline C</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline D</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline E</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline F</div>
<div class="text">Some kind of Content</div>
</div>
</div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
I don't guarantee it will work the way you envision, so it will be good to give it a proper test.
It should basically pull a random div from the ".directory" div for each ".box".
It relies on the fact, that when we select a div from ".directory" we actually remove it from ".directory" to put it in ".box" so even if the random function returns the same index, on the second pass, the div there will be different.
EDIT : #Pavel Donchev solution is better :)
It's better for you to change the CSS style of your elements to display them, or not.
To choose a define number of random elements, you can do it like this :
function randomContent(numberOfElements){
var i = 0;
var randomElements = $(".content").get().sort(function() {
return Math.round(Math.random()) - 0.5;
}).slice(0, numberOfElements);
while(i < randomElements.length) {
if($(randomElements[i]).hasClass('show')){
break;
}
else{
$(randomElements[i]).addClass('show');
i++;
}
}
}
randomContent(3);
.content {
display: none;
margin-bottom: 20px;
border-bottom: 1px solid black;
padding-bottom: 10px;
}
.show{
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="directory">
<div class="content">
<div class="headline">Headline A</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline B</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline C</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline D</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline E</div>
<div class="text">Some kind of Content</div>
</div>
<div class="content">
<div class="headline">Headline F</div>
<div class="text">Some kind of Content</div>
</div>
</div>
Working JSFiddle : https://jsfiddle.net/2m9tdgn2/
Hi as per undersanding below code will solve your problem easily just put that code under script tag. also include jquery.min.js in your html. to avoide $ is undefined :)
$(document).ready(function(){
drawRandomDivContent();
});
function drawRandomDivContent()
{
var container=$(".content");
var array=[];
var dataarray=[]
for(var i=0;i<container.length;i++)
{
var number=getRandomInt(container.length);
if($.inArray(number,array)==-1)
{
var selectedDiv=container[number];
dataarray.push(selectedDiv);
array.push(number);
if(array.length==3)
break;
}
}
var destinationdiv=$(".box");
for(var i=0;i<dataarray.length;i++)
destinationdiv[i].innerHTML=dataarray[i].innerHTML;
}
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}

Counting element's div's by using mocha testing framework

I have picked up an WebElement JSON objects by using xpath, this item is a div which has div's inside it.
it('Count terminals in view', function() {
elems = browser.elements('/html/body/div[2]/ui-view/div/div[1]/div[4]/div[2]');
console.log(elems.value);
});
The html code looks like this
<div class="col-lg-8 col-md-pull-0 col-lg-pull-4">
<div class="col-lg-12">
<div style="margin: 10px 0px 10px 0px;">
<div class="row">
<div class="col-lg-4">
<div>Hardware Id</div>
<div ng-bind="terminal.hardwareId" style=" cursor: pointer; width: 100%" ng-click="downloadVM.openModal(terminal.hardwareId);" class="ng-binding">S8EVMOC00019</div>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div style="margin: 10px 0px 10px 0px;">
<div class="row">
<div class="col-lg-4">
<div>Hardware Id</div>
<div ng-bind="terminal.hardwareId" style=" cursor: pointer; width: 100%" ng-click="downloadVM.openModal(terminal.hardwareId);" class="ng-binding">S8NOMOT00049</div>
</div>
</div>
</div>
</div>
</div>
I need to be able to count the hardwareId's they are changeable, how can I loop properly through them?
Found a way to do the counting of the div's, just added an wild card "*" to the top div, and then looped through the count variable.
count = browser.elements('/html/body/div[2]/ui-view/div/div[1]/div[4]/div[2]/*');
console.log(count);
for (el in count.value) {
console.log(el);
}

How to .Clone div without cloning the wrapper

How to clone the content of a div without copying the div itself with it?
I use this function, but it copies div-1 inside div-2.
$(function(){
var $div = $('.div-1').clone();
$('.div-2').html($div);
});
HTML:
<div class="div-1">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="div-2">
</div>
<div class="div-2">
</div>
GOAL:
<div class="div-1">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="div-2">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="div-2">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
You can clone the children elements using:
$(function(){
var $div = $(".div-1").children().clone(true,true);
$('.div-2').html($div);
});
Working Demo
You need to clone he children
$(function(){
var $div = $('.div-1').children().clone();
$('.div-2').html($div);
});
$('.div-2').html($('.div-1').html());
Try this it will work

Counting all Item class elements before and after header classes

Hey I am thinking of a Jquery solution to a problem. Below you can see I have items that follow after each heading now this is fine.
<div class="header"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="header"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="header"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
But there are times when there will be no items. Just headers:
<div class="header"></div>
<div class="header"></div>
<div class="header"></div>
<div class="item"></div>
In this case I would like to check if there are any items after each header. If there is none add paragraph text "Not Available" Like so:
<div class="header"></div>
<p>Not Available</p>
<div class="header"></div>
<p>Not Available</p>
<div class="header"></div>
<div class="item"></div>
Many Thanks for any help.
See if this works :
$('.header').filter(function(){
return $(this).next().hasClass('header');
// or return !$(this).next().hasClass('item');
}).after('<p>Not Available</p>')
This is my idea for you:
- You can add a class name groups to include the header class and the items class, like this:
<div class="groups">
<div class="header"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="groups">
....
</div>
....
Now you have a lot of groups. What you have to do is count every group and check if item exist or not:
$('.groups').each(function(){
if($(this).children('items').length > 0){
// found items class
}
else{
// not found any items class
$(this).append('<p>Not Available</p>');
}
});

Categories

Resources