jQuery - get index of element, restricted to class - javascript

Given the following html:
<div class="my-container">
<div class="x">
Link 1
</div>
<div class="x">
Link 2
</div>
<div class="x">
Link 3
</div>
<div class="x y">
Link 4
</div>
<div class="x">
Link 5
</div>
<div class="x y">
Link 6
</div>
<div class="x">
Link 7
</div>
</div>
Which elements get the y class - is a dynamic thing, which changes during runtime based on different user interactions.
On mouse over an anchor (I can assume that the anchor is in a div with the y class, because only those are visible), I need to get the index of it's container (that div with the y class), but restricted to that y class.
Meaning:
mouseover on "Link 4" should tell me: 0 (first element with class y)
mouseover on "Link 6" should tell me: 1 (second element with class y)
.index() doesn't help me here
EDIT:
#Kevin B
I've read the docs, but couldn't make it work. The closest thing I could find there was to pass a collection to .index(), which I've tried. But didn't work (also, their example for the collection is with vanilla js document.getElementById - that didn't work for me, need to work with classes; tried to adapt: myCollection = $(this).closest('.my-container').children('.y') and passed that to .index(), and it didn't work).
I wouldn't post without google-ing first and also going through the docs, don't know why the down vote (not pointing any fingers, I'm not assuming I know who's is it). Just because I said ".index()" doesn't help me"? Well, I've tried whatever I understood I could do with it, and couldn't make it happen. That's why I posted.

As said in the comments, index is exactly what you need:
$(document).ready(function() {
//mousein
$("a").hover(function(){
var parent = $('.my-container').eq(2); // the 3rd "my-container"
console.log(parent.find('.y a').index(this)); //-1 if elm doesnt exist
},
//mouseout
function(){
})
});

As said in the comments, index is exactly what you need:
$(document).ready(function() {
//mousein
$("a").hover(function(){
console.log($(this).index('.y a')); //-1 if elm doesnt exist
},
//mouseout
function(){
})
});

var count = 1;
$(".my-container div").on('mouseover',function(){
if ($(this).attr("class").indexOf('y') > -1){
alert(count + "th mouseover on y class");
count++;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="my-container">
<div class="x">
Link 1
</div>
<div class="x">
Link 2
</div>
<div class="x">
Link 3
</div>
<div class="x y">
Link 4
</div>
<div class="x">
Link 5
</div>
<div class="x y">
Link 6
</div>
<div class="x">
Link 7
</div>
</div>

Related

How to edit childrens div?

I have this HTML code (and the number of components that I want to edit it's variable, it could be 3 or 20).
I have created a small example with similar scenario on my website
As you can see my script is able to edit the father div and add the classname. Same for firstchild.
I would like to edit all divs inside firstchild but not the immediately div, it has to be two inside.
Any ideas why my code is not working on the last part?
Thanks.
// WORKS OK
var firstc = document.getElementById('father');
firstc.classList.add("father-class");
firstc.children[0].children[0].children[0].setAttribute("id", "firstchild"); // WORKS OK
var second = document.getElementById('firstchild');
second.classList.add("child-class");
// NOT WORKING
var grandchildren = second.children[0].children[0].children[0];
for (let z = 0; z < grandchildren.length; z++) {
grandchildren[z].classList.add("slide");
}
<div id="father">
<div>
<div>
<div id="firstchild">
<div>
<div>
<div class="random63637236">
<li>1</li>
</div>
<div class="generic">
<li>2</li>
</div>
<div class="italy_gdgd">
<li>3</li>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
the problem in your code is the last children[0]. you are selecting only the first div, it's not an array. Fix that line and everything will work
var grandchildren = second.children[0].children[0].children;
As a side note: if for some reason the first or the second .children[0] are undefined you will get an error.
A better approach is to use querySelectorAll which returns an array;
if your array it is empty, nothing happens.
second.querySelectorAll('#firstchild > div > div > div')
.forEach(el => el.classList.add('slide'))

Using classes instead of IDs

I have two divs in my parent class, one of which is found by $(this).parent('div').next('.deal-rolldown').show(); the other, $(this).parent('div').next('.client-rolldown').show(); does not find what appears to by syntactically equal.
In WordPress I iterate an (unknown) number of posts, each has 2 buttons to reveal more content. Up to now I have run a document ready function in each iteration to address each reveal by IDs but this is inefficient.
So I am trying to write a function using classes. Here's the JavaScript
$('.deal-link').click(function() {
$('.deal-rolldown').hide(); // hide all
$('.client-rolldown').hide(); // hide all
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
$(this).next('.deal-rolldown').show();
}
});
$('.client-link').click(function() {
$('.client-rolldown').hide(); // hide all
$('.deal-rolldown').hide(); // hide all
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
$(this).next('.client-rolldown').show();
}
});
Which is operating on this HTML
<div class="company">
<div class="company-inner">
<h2>Company 1 </h2> Company 1 Summary
</div>
Deal summary
Client review
</div>
<div style="display: none;" class="deal-rolldown">
Company 1 reveal 1 content
</div>
<div style="display: none;" class="client-rolldown">
Company 1 reveal 2 content
</div>
<div class="company">
<div class="company-inner">
<h2>Company 2 </h2> Company 2 Summary
</div>
Deal summary
Client review
</div>
<div style="display: none;" class="deal-rolldown">
Company 2 reveal 1 content
</div>
<div style="display: none;" class="client-rolldown">
Company 2 reveal 2 content
</div>
The addClass('active') works fine so I know I am getting the right button, but the next() function does nothing. No errors. How can I select the appropriate reveal from each button?
Edit following closure: this is a different question to the one marked as duplicate.
First thing, instead of doing
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
You can use $(this).toggleClass('active');
Your problem is that next() returns the immediately following sibling, and .deal-rolldown is not a sibling of your .deal-link element.
What you want to do is
$(this).parent('div').next('.deal-rolldown').show();
The next() function gets the immediately following sibling that matches the selector. The div with class '.deal-rolldown' is NOT a sibling of the '.client-link' or '.deal-link' links. I would suggest using .closest('.deal-rolldown') instead of .next() which will find the closest matching element by traversing up through the current item's ancestors.

jQuery: how to get the index of an element in the selection array?

I have an HTML structure like this:
<div class="container">
<div class="item">
1
2
3
</div>
<div class="item">
4
5
6
</div>
</div>
I select all the A-s with jQuery, and get a total of 6 objects here. I want to get the index of the A in the array of 6 (so I can detect which A has been clicked, for example), but when I use .index() I get the index of the element relative to its parent. So for the 5th A I get the same index as for the 2nd, because te 5th is actually the second in its group within its div.item:
$('a').click(function(){
console.log ( $(this).index() ); // returns "1" for the 5th A
});
So is there a way to get the index of the clicked element within the array of the selection, instead of within the parent in the DOM?
You can pass the clicked element to the index method:
var $a = $('.container > .item > a').click(function() {
console.log ( $a.index(this) );
});
Take a look at jquery documentation for .index(). You could modify your code as following to get the desired result:
$('.container').on("click", "a", function(){
console.log ( $("a").index($(this)));
});
$('a').click(function(){
$("#result").text($('a').toArray().indexOf(this));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
1
2
3
</div>
<div class="item">
4
5
6
</div>
</div>
<div id="result"></div>

filtering and sorting divs

I have been looking for a robust and simple way to sort my casestudies but after a couple of hours and a search of stack overflow i could not find a way to filter casestudies the way I want.
Basically I will give each casestudy three categories (year produced, type of project and name) using css classes, for example the markup would look something like this
<div class="name1 home 2013"></div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
<div class="name5 home 2010"></div>
<div class="name6 work 2007"></div>
Then I want to have buttons so you can choose which category you want to sort the casestudies by. So something like.
<div class="button" id="year">Sort by Year</div>
<div class="button" id="alpha">sort Alphabetically</div>
<div class="button" id="type">sort by type</div>
This is where I am getting stuck. What javascript function can i create so that if you click the button "sort by year" it will create a mark up that looks like this. eg sorting all the casestudies in to divs with casestudies of the same year.
<div>
<div class="name1 home 2013"></div>
</div>
<div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
</div>
<div>
<div class="name5 home 2010"></div>
</div>
<div>
<div class="name6 work 2007"></div>
</div>
I would use data attributes to make the filtering easier.
<div class="name1 home" data-year="2013">2013</div>
<div class="name2 work" data-year="2012">2012</div>
<div class="name3 home" data-year="2012">2012</div>
<div class="name4 charity" data-year="2012">2012</div>
<div class="name5 home" data-year="2010">2010</div>
<div class="name6 work" data-year="2007">2007</div>
The using JQuery and array.map (could be replaced with a foreach if you want older browser support)
var studies = $('[data-year]')
studies.map(function(index, el) {
var $el = $(el)
year = $el.attr('data-year')
if($('#' + year).length == 0){
$(document.body).append(
$('<div>').attr('id', year)
.css('margin-bottom', '20px')
)
}
$('#' + year).append(el)
})
what this does is take all the elements with a data-year attribute, foreach element check to see if a div with the id of that elements year exists. If it doesn't create one and append it to the body. Then it appends the element into the year container.
see this jsfiddle

How to show the first n number of elements in jQuery?

I have a page that has 50 elements with the same class "fields" which are all display none at the moment
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
...
How to I only show the first 3 or whatever number. Plus count them with a count on top like the following example below.
So for example if I needed the first 3 this is what i need the divs to look like
<div class="fields">
<h1>Station 1</h1>
</div>
<div class="fields">
<h1>Station 2</h1>
</div>
<div class="fields">
<h1>Station 3</h1>
</div>
<div class="fields" style="display:none;">
...
</div>
...
So basically only some the number of divs that I need...I already have the number of elements I need to show in this blur statement in the station_count variable. Also notice i need a span tag with the count..any ideas on how to do this
$("#number_station").blur(function(){
var station_count = $(this).val();
//code goes there
});
How to I only show the first 3 or whatever number.
$('div.fields:lt(3)').show();
Plus count them with a count on top
$('div.fields:lt(3)').each(function (index)
{
$('<h1></h1>', {text: 'Station ' + index}).prependTo(this);
}).show();
Demo: http://jsfiddle.net/mattball/TssUB/
Read the jQuery API docs for basic questions like this:
:lt() selector
.prependTo()
jQuery() (for creating new elements)
While the other answers will work, I recently discovered and love the jQuery slice() method.
$(".fields").slice(0, 3).each(function(index) {
// Do whatever you want to the first three elements
}
With
$(".fields").each(function() {
//do whatever like count then show/hide
});
you can iterate over the hidden divs. So with a simple variable you can start/stop whenever you need.

Categories