Selecting the .index() of a deeply nested element - javascript

I want to select the tags onlu inside a by the index shown in the link names. What is the best method of doing this?
<div class="index-get">
<div class="column">
Category Title
<ul>
<li>Index 0</li>
<li>Index 1</li>
<li>Index 2</li>
<li>Index 3</li>
<li>Index 4</li>
</ul>
</div>
<div class="column">
<ul>
<li>Index 5</li>
<li>Index 6</li>
<li>Index 7</li>
<li>Index 8</li>
<li>Index 9</li>
</ul>
</div>
</div>
$('.index-get ul a').click(function(){
var aIndex = $(this).index();
console.log(aIndex);
});

var aIndex = $('.index-get li a').index($(this));
and you should cache $('.index-get li a') outside of the event handler
var $lia = $('.index-get li a');
$lia.on('click',function() {
console.log($lia.index($(this)));
})

Not sure if the question is clear enough but here is something that might relate to what you need:
$('.index-get ul a').click(function(){
var aIndex = $(this).text();
console.log(aIndex);
});
And the fiddle.
EDIT
I think I finally got it the question sigh... :-)
Since there is only one A inside each parent LI the index of A tags will always be 0 in your example because the index is in relation to the sieblings...
If you calculate the index for the LI you might get better result. But keep in mind the index is only counted inside each parent so for the two ULs you will get two sets of LI children hence clicking Index 1 or Index 6 will yield the same result.
New Fiddle
One more edit
Actually the ULs are nor sieblings and one must go above to the DIV and down again into the ULs to be able to count the LI of previous items... But I guess it works just perfect for your needs. I I understood your needs that is... ;-)
$('.index-get ul li').click(function(){
var aIndex = $(this).index()+$(this).parent().parent().prev().find("ul").children().length;
console.log(aIndex);
});
And the fiddle.
Last edit
Making the line slightly simpler
var aIndex = $(this).index() + $(this).parent().parent().prev().find("ul li").length;
&(this) is an LI element.
$(this).parent() is the UL
$(this).parent().parent() is the DIV
$(this).parent().parent().prev() are all the sibling elements of that DIV (hopefully only DIVs in there and all with the same type of content)
$(this).parent().parent().prev().find("ul li") all LI inside UL inside sibling DIVs.
$(this).parent().parent().prev().find("ul li").length; the number of LI in the previous line.
There you go. Simple logic! ;-)
And when you think all is done and settled... There comes one more edit!!! :-)
I was thinking of the solution I proposed and it will eventually fail if you have more then two UL groups and if you click on a LI located in the third UL or later.
Therefore I have created yet another solution which uses .prevAll() instead of just .prev() but then must use the .each() with a function to add up all the count of all LI elements from the previous ULs.
Fiddle
Now I can go sleep in peace! :-)
Fabricio

Try this code:
$('.index-get ul a').click(function(){
var aIndex = $(this).text().match(/\d+$/)[0];
console.log(aIndex);
});

This should work no matter how deep the li's are nested:
var items = $('li');
items.on('click', function() {
var clicked_item = $(this);
items.each(function(index){
if ($(this).is(clicked_item)){
console.log(index);
}
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="index-get">
<div class="column">
Category Title
<ul>
<li>Index 0</li>
<li>Index 1</li>
<li>Index 2</li>
<li>Index 3</li>
<li>Index 4</li>
</ul>
</div>
<div class="column">
<ul>
<li>Index 5</li>
<li>Index 6</li>
<li>Index 7</li>
<li>Index 8</li>
<li>Index 9</li>
</ul>
</div>
</div>

Related

Javascript NodeList.forEach() not updating all found items

I don't understand why this function only seems to update the last item in the nodelist. I want the function to add the indicator element to all li elements that have a child ul element. The function finds all the elements, but only the last one seems to get updated.
var ulElementsWithChildren = document.querySelectorAll('ul.test>li ul');
var indicator = document.createElement('span');
indicator.innerHTML = '+';
ulElementsWithChildren.forEach(function(item) {
item.parentElement.appendChild(indicator);
});
html
<ul class="test">
<li>Item 1</li>
<li>Item 2
<ul>
<li>Child Item</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4
<ul>
<li>Child Item</li>
</ul>
</li>
<li>Item 5
<ul>
<li>Child Item</li>
</ul>
</li>
</ul>
JS Fiddle
You create one <span>.
You then append it in lots of different places.
Since an element can only appear in one place, you move it each time until you get to the end of the loop.
You need to create a new span each time you go around the loop.
Move your indicator declaration inside of your foreach and it will work.
example:
ulElementsWithChildren.forEach(function(item) {
var indicator = document.createElement('span');
indicator.innerHTML = '+';
item.parentElement.appendChild(indicator);
});
You're only creating a single span element.

jQuery Sortable - moving elements between list with Double-Click

I would like to add a functionality to the original jQuery Sortable Connect List example at: http://jqueryui.com/sortable/#connect-lists
Since my second list (#sortable2) is kind of large... I would like to be able to scroll the page down and once I found the item that I need to select/move... just Double.Click on it in order to move it to the other list.
I need to move the items (li) from #sortable2 to #sortable1 as well as from #sortable1 to #sortable2. The idea is just to Double-Click and not Dragging.
THANKS!
Your html
<ul id="sortable1" class="sortable_list connectedSortable">
<li class="ui-state-default">sortable1 Item 1</li>
<li class="ui-state-default">sortable1 Item 2</li>
</ul>
<ul id="sortable2" class="sortable_list connectedSortable">
<li class="ui-state-default">sortable2 Item 1</li>
<li class="ui-state-default">sortable2 Item 2</li>
</ul>
Only from id = sortable2 you will have the items appended to sortable1 with li.class = ui-state-default. This adds one li item at a time from sortable2 to sortable1 .
script
//attach on load
$(function() {
$("#sortable2 .ui-state-default").dblclick(function(){
$("#sortable1").append(this);
});
});
$(function() {
$("ul li").dblclick(function(){
var parentID = $(this).parent().attr('id'); //sortable1 or sortable2
if(parentID.match(/^(sortable1)$/g))
$("#sortable2").append(this);
else if(parentID.match(/^(sortable2)$/g))
$("#sortable1").append(this);
});
});

Add css style to elements of 2 lists on element click

I have 2 lists of elements. When I click on an element of first list (it is a link), I basically need to add css class 'is-active' to that element AND to corresponding item from another list. I think they have to be in separate lists, as they are in two different bootstrap columns for mobile friendliness. I am currently styling elements from first list with:
$(document).ready(function(){
$('.tabs li').click(function(){
$(this).addClass('is-active');
$('.tabs li').not(this).removeClass('is-active');
});
})
Can't select elements from the other list though.. Any ideas how can I achieve this functionality with css, js/jquery?
My html structure currently is like this:
<div class="col-md-6">
<ul class="tabs">
<li class="tabs-title is-active">
title_1
</li>
<li class="tabs-title">
title_2
</li>
</ul>
</div>
<div class="col-md-6">
<div class="tabs-content">
<div class="tabs-panel is-active">
<div class="entry">
<p>content_1</p>
</div>
</div>
<div class="tabs-panel">
<div class="entry">
<p>content_2</p>
</div>
</div>
</div>
</div>
When I click on 2nd link from first column, the 2nd div from second column should get 'is-active' class. Is this possible?
I guess lists do not have corresponding elements right now. What do I need to have the items linked in some way?
Here's an example, since we don't know what your list looks like.
<ul class="tabs">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
<ul class="letters">
<li>item a</li>
<li>item b</li>
<li>item c</li>
</ul>
Also, it's easier to remove all instances of the is-active class and then add it just to the target elements.
$(document).ready(function(){
$('.tabs li').click(function(){
var index = $('.tabs li').index(this);
$('.tabs li, .letters li').removeClass('is-active');
$(this).addClass('is-active');
$('.letters li').each(function(i) {
if (i == index)
$(this).addClass('is-active');
})
});
})
https://jsfiddle.net/fzeauw7a/

Jquery If class has matching ID then hide

What I'm trying to do here is check if an element has the same id as a class in another element if so hide the matching id.
So far this is what I have came up with but it doesn't seem to kick.
JSfiddle
var theid = $('#me li').attr('id');
if ($('#you li').hasClass( theid )) {
$('#me li#'+theid+'').hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul id="me">
<li id="num-0">iam 1</li>
<li id="num-1">ieam 2 & should be hidden</li>
<li id="num-2">iam 3</li>
<li id="num-3">iam 4</li>
<li id="num-4">ieam 5 & should be hidden</li>
<li id="num-5">iam 6</li>
</ul>
<ul id="you">
<li class="num-1">iam killer</li>
<li class="num-4">iam killer</li>
</ul>
Use each() to loop over all the li elements inside the #you
hide() the elements having the id same as the class of current element in loop.
$('#you li').each(function() {
$('#' + $(this).attr('class')).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul id="me">
<li id="num-0">iam 1</li>
<li id="num-1">ieam 2</li>
<li id="num-2">iam 3 & should be hidden</li>
<li id="num-3">iam 4</li>
<li id="num-4">ieam 5 & should be hidden</li>
<li id="num-5">iam 6</li>
</ul>
<ul id="you">
<li class="num-2">iam killer</li>
<li class="num-4">iam killer</li>
</ul>
Demo
When you use the .attr() method on a jQuery object that contains multiple elements, it just returns the attribute from the first element. You need to loop over each element and check them one at a time.
It is, however, OK for your purposes to use .hasClass() on the set of all of the #you elements, because .hasClass() will return true if any of the elements in the set has that class. So:
var you = $('#you li');
$('#me li').each(function() {
if (you.hasClass(this.id))
$(this).hide();
});
Note that I'm keeping a reference to the $('#you li') jQuery object in the variable you to save selecting those elements again every time in the loop.
Demo: https://jsfiddle.net/d65sz4js/2/
Try this for your jquery:
$(function() {
$("#you li").each(function(){
var theid = $(this).attr('class');
$('#'+theid).hide();
});
});
Demo: https://jsfiddle.net/nkem9o7o/
You could filter the #me li's, returning elements where their id exists as a class in #you li's, then just hide them. This would also work for multiple classes:
$('#me li').filter(function() {
return $('#you').has('.' + this.id).length;
}).hide();
Here's a fiddle

Select jquery elements except specific children

This is a simple question, but, I haven't found a clear answer in any of the question that I found. I modified a JSFiddle for my specific question.
I got this tiny code:
<ul>
<li id='one'>Element 1</li>
<li id='two'>Element 2</li>
<li id='three'>Element 3</li>
<li id='four'>Element 4</li>
<li id='five'>Element 5</li>
</ul>
and this script should return the ul element excepting the first li:
$(function(){
$("ul").not($('#one'))
});
Instead, it removes every li. What have I done wrong?
EDIT: In others words, I would like a selector which selects this, without removing the actual element (= inside a variable)
<ul>
<li id='two'>Element 2</li>
<li id='three'>Element 3</li>
<li id='four'>Element 4</li>
<li id='five'>Element 5</li>
</ul>
FIDDLE: http://jsfiddle.net/LVUMs/13/
Use
$("ul li").not($('#one')).remove();
DEMO
OR
$("ul li:not(#one)").remove();
DEMO 2
EDIT
You need
var ulexceptOneLi = $("ul li:not(#one)");
or
var ulexceptOneLi = $("ul li").not($('#one'));
Try this code:
Fiddle
$(function(){
$("ul>li").not($('#one')).empty();
});
Assuming you meant to keep the ul in play:
$("ul li#one").remove();
Here's a fiddle...
If you're wanting to return a ul element with the removed element inside, try this:
function do_crazy_thing(){
var removed = $("ul li#one").remove();
return $('<ul></ul>').append(removed);
}
do_crazy_thing();
Here's another fiddle...
Here's how you would then append your new ul element to the body...
Demo Fiddle
According to your question, your expected output is :
<ul>
<li id='two'>Element 2</li>
<li id='three'>Element 3</li>
<li id='four'>Element 4</li>
<li id='five'>Element 5</li>
</ul>
Check the demo.
Edit :
$(function(){
var removed = $("ul li:not(#one)");
});
OR
var op = $("ul :not(#one)");
Please try below JS code
$(function(){
var test= $("ul li").remove("#one");
});

Categories