How to know the order number of the child element selected in relation to its parent? - javascript

I have a html structure like the following:
<div id="first">
<div id="second">
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
<div class="inside"></div>
</div>
</div>
And the following javascript / jquery code:
$(".inside").mouseover(function(ev){
var el = ev.currentTarget;
//TODO: get real element
var el_position = 1;
});
What I want to do is check the number of ".inside" that is being hovered with the mouse. So, if I hover the first entry of ".inside" it should display "1". In the fourth it should display "4". But accessing the variable "el" (ev.currentTarget) has no "element position" property or anything of the alike that would allow me to understand the position of the actual hovered element in relation to "#second" (the first, second, third, etc .inside).
So, does anyone have any idea? Can I get some help? Thank you very much :)

You can use .index() which returns the 0-based index of the element within a collection
$(".inside").mouseover(function(ev) {
var el = ev.currentTarget;
//TODO: get real element
var el_position = $(el).index(".inside") + 1;
console.log(el_position);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="first">
<div id="second">
<div class="inside">1</div>
<div class="inside">2</div>
<div class="inside">3</div>
<div class="inside">4</div>
<div class="inside">5</div>
</div>
</div>

Related

Find the index of a div inside a container

I have a container with multiple divs and in each div I have a handler on which you can click.
The requirement is to return the index of the div in the container for further processing.
I've simplified the code for readability purposes.
The HTML:
<div class="container">
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
</div>
The Javascript code I tried so far but I always get -1 as the index:
$(document).ready(function(){
$('.handler').click(function(e) {
let index = Array.prototype.indexOf.call($('.container'), $(this).parents('.block'));
console.log(index);
});
});
I also created a fiddle.
So what am I doing wrong here?
You can do the following,
$('.handler').click(function(e) {
var el = e.target;
console.log([].indexOf.call(el.parentNode.parentNode.children, el.parentNode));
});
However if you want to know what was wrong in your code,
Array.prototype.indexOf.call($('.container')[0].children, $(this).parents('.block')[0])
This part should fix the problem in your code. You have been doing it all right, but for the parameter of indexOf we needed the children array of .container and clicked element.
You were passing the container element and current clicked element as an array. That is Array.prototype.indexOf.call('[Container Element]', ['current clicked div']) Which is not right. You should pass something like this,
Array.prototype.indexOf.call('[children, children, children...]', 'current clicked div element').
It was happening because the $('.container') returns an array with the element having a class name .container. But we needed all the children array of the element that contains container class.
And $(this).parents('.block') returns an array with the matching elements even if it is only one.
You can access the index using the index method on parent element of selection.
$(document).ready(function(){
$('.handler').click(function(e) {
console.log($(this).parent().index())
});
});
You can do that like this. Find the index of the closest element of the clicked element, which is also a direct child of .handler. To find index, use index().
$(document).ready(function() {
$('.handler').click(function(e) {
let index = $(this).closest('.block').index()
console.log(index);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
<div class="block">
<div class="handler">
Click
</div>
</div>
</div>
You're checking at the wrong level of nesting in your HTML. I believe what you're trying to do is check from one level higher, at ".container" and get the index of the ".block" element that was clicked.
This code works in your Fiddle:
$(document).ready(function(){
$('.handler').click(function(e) {
const p = e.target.parentElement.parentElement;
const index = Array.prototype.indexOf.call(p.children, e.target.parentElement);
console.log(p.className) // "container"
console.log(index)
});
});
This can be done simply using delegate in jQuery.
I modify your JSFiddle code.
$(".container").delegate('.block', 'click', function () {
console.log( $(this).index() );
})
u can use a id
<div class="container">
<div class="block">
<div id='0' class="handler">
Click
</div>
</div>
<div class="block">
<div id='1' class="handler">
Click
</div>
</div>
<div class="block">
<div id='2' class="handler">
Click
</div>
</div>
<div class="block">
<div id='3' class="handler">
Click
</div>
</div>
</div>
$(document).ready(function(){
$('.handler').click(function(e) {
let index = this.id
console.log(index);
});
});
https://jsfiddle.net/vhrt596x/2/

How do I set data attribute value by the index of element in jQuery?

I have multiple sibling elements, some that are added dynamically and others manually or using JS. Each one has a data attribute of "data-sec_number" with a number value that increases by one for each new element down the page. At the moment I am manually writing these in.
E.g.
<div class="container">
<div class="row resource_sec" data-sec_number=1>
<div class="content sec_number" data-sec_number=1></div>
</div>
<div class="row resource_sec" data-sec_number=2>
<div class="content sec_number" data-sec_number=2></div>
</div>
<div class="row resource_sec" data-sec_number=3>
<div class="content sec_number" data-sec_number=3></div>
</div>
</div>
How can I get the value of attribute "data-sec_number" to match the index of the element .resource_sec within the .container element? E.g. the 3rd .resource_sec element will always have a "data-sec_number" value of 3.
I also have the child element of .resource_sec called .sec_number, which has the same data attribute that should mirror the parent.
The JS I have been trying to use is:
var items = $('.container .resource_sec');
var lastItem = $('.container .resource_sec:last');
var index = items.index(lastItem);
$('.resource_sec').attr('data-sec_number', index);
$('.sec_number').attr('data-sec_number', index);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="row resource_sec" data-sec_number=1>
<div class="content sec_number" data-sec_number=1></div>
</div>
<div class="row resource_sec" data-sec_number=2>
<div class="content sec_number" data-sec_number=2></div>
</div>
<div class="row resource_sec" data-sec_number=3>
<div class="content sec_number" data-sec_number=3></div>
</div>
</div>
The meaning of this line
$('.resource_sec').attr('data-sec_number', index);
is to set the attribute value. to select (query) a specific index please use:
$('.resource_sec[data-sec_number=' + index + ']')
or
$(`.resource_sec[data-sec_number=${index}]`)
If you support ES6
UPDATE:
To add a new element in jQuery you may use:
var container = $('.container')
var newElement = $('<div class="row resource_sec"></div>').appendTo(container)
Then, you can fetch the new element index by passing it to the index method,according to Jquery documentation:
If .index() is called on a collection of elements and a DOM element or jQuery object is passed in, .index() returns an integer indicating the position of the passed element relative to the original collection.
var index = container.index(newElement)
To append index to the new element attribute:
newElement.attr('data-sec_number', index)

Insert div as the .lastElementChild without 'insertBefore' without jQuery

Okay so I've usually had .box-4 as the last element inside of .s1 as shown below:
<div class="s1">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
</div>
and had .box-1 move before .box-4 using the JavaScript:
var box1 = document.querySelector('.box-1');
var s1 = box1.parentNode;
s1.insertBefore(box1, s1.lastElementChild);
to receive the following outcome:
<div class="s1">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-1"></div>
<div class="box-4"></div>
</div>
however, I have recently removed .box-4 from .s1, and consequently .box-1 no longer move/becomes the .lastElementChild. I would still like .box-1 to move, and hence become last, however, I'm unsure of what command will achieve this; desirably something like this
.insertAs(box1, s1.lastElementChild);
to achieve this:
<div class="s1">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-1"></div>
</div>
NOTE: .box-1 changes position depending on screen-width, so simply moving the div in HTML is not an option.
NOTE: Vanilla JavaScript only - No jQquery.
Thanks in advance guys, much appreciated!
Below will append box1 as the last child (automatically removes it from it's original position).
var box1 = document.querySelector('.box-1');
var s1 = box1.parentNode;
s1.appendChild(box1);
To insert HTML without jQuery simply use insertAdjactedHTML function.
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
Just use .appendChild?
const box1 = document.querySelector('.box-1');
const s1 = box1.parentElement;
box1.remove();
s1.appendChild(box1);
<div class="s1">
<div class="box-1">b1</div>
<div class="box-2">b2</div>
<div class="box-3">b3</div>
<div class="box-4">b4</div>
</div>

jquery clone a link (once per div)

I have a set of divs, and need to clone the link from the top and insert into the last div (mobile-link). It is either cloning the links from all of the divs, and then inserting all of them at once, or if I use :eq(0), it's putting the first link into all of the divs.
<div class="course">Accounting</div>
<div class="start-date">1-1-2017</div>
<div class="credits">4</div>
<div class="location">Online</div>
<div class="mobile-link"></div>
<div class="course">Business</div>
<div class="start-date">1-1-2017</div>
<div class="credits">3</div>
<div class="location">Online/Campus</div>
<div class="mobile-link"></div>
<script>
$(".course a:eq(0)").clone().appendTo(".mobile-link");
</script>
What do I need to change to make this work properly?
You need to process each anchor separately:
$(".course").each(function() {
var myLink = $(this).find('a').clone();
$(this).nextAll('.mobile-link').first().append(myLink);
});
Demo fiddle
Append method can take a function as argument, and here it is appending to the each .mobile-link first <a> from his previous .course div
$(".mobile-link").append(function(){
return $(this).prevAll('.course:first').find('a:first').clone();
});
Check the below snippet
$(".mobile-link").append(function(i) {
return $(this).prevAll('.course:first').find('a:first').clone();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="course">Accounting
</div>
<div class="start-date">1-1-2017</div>
<div class="credits">4</div>
<div class="location">Online</div>
<div class="mobile-link"></div>
<div class="course">Business
</div>
<div class="start-date">1-1-2017</div>
<div class="credits">3</div>
<div class="location">Online/Campus</div>
<div class="mobile-link"></div>
I beleive that you should use last (If I understood question correctly):
var lastDiv = $(".mobile-link").last();
$(".course a:eq(0)").clone().appendTo(lastDiv);
Here is jsfiddle: fiddle

Is it possible to re-assign a div's childs class in consecutive order with Jquery

I have the following situation where my divs childs id's need to be renamed in consecutive order starting from 1.
eg.
<div id="parent">
<div id="child-108"></div>
<div id="child-99"></div>
<div id="child-9"></div>
<div id="child-18"></div>
<div id="child-64"></div>
</div>
converted via JQuery or regular Javascript into:
<div id="parent">
<div id="child-1"></div>
<div id="child-2"></div>
<div id="child-3"></div>
<div id="child-4"></div>
<div id="child-5"></div>
</div>
Any help would be great!
Sure, you can do that with the each function:
$('#parent > div').each(function(index) {
this.id = 'child-' + (index + 1);
});
The function you pass into each is called with this pointing at the DOM element and the index argument giving the index (starting with 0) within the selected elements.

Categories

Resources