How to deal with the .next() function with hidden elements - javascript

I am making a custom drop down menu with arrow key functions as well as being filtered by :contains.
I can't seem to get past the following code. What is happening is that I need to start the selection at the current hovered li, then proceed to the next or previous li that has the class match.
My following code starts correctly but even though it has .next('.match') it wont pass the <li>'s that either don't have the class (match) or are (hidden)
Does the next() function break on hidden elements?
Jquery Code
$('.dropdown_shell.opened li.match.hovered')
.next('.match')
.addClass('hovered')
.siblings()
.removeClass('hovered');
Html
<ul class="scroll">
<li class="selected default match">None</li>
<li class="" style="display: none;">For Sale</li>
<li class="match">For Rent</li>
<li class="" style="display: none;">For Lease</li>
<li class="match hovered">Sale or Lease</li>
<li class="match">New Listing</li>
<li class="match">Open House</li>
</ul>

Your next() function is not doing what you think it is. It looks at the next element, and only matches it if it makes the given selector. Otherwise it returns an empty jQuery object.
Instead, you want nextAll(), which looks at all future siblings, then use the first() method (or :first) selector to match the first one.
You can see this working here; http://jsfiddle.net/DH3hG/
To answer your question about whether next() considers hidden elements; yes it does. Anything that is inserted into the DOM is considered.

Related

AngularJS drag and drop Checking whether the item raised has a class

I have a question, I have created ng-repeat which i print out li with the names.
then after catching the li element The dndDragging class is added(to li).
And now I have a question how to check if this class has been added, after after pick up item?
Could someone tell me how to do it?
<ul dnd-horizontal-list="true"
dnd-list="board.lists"
dnd-allowed-types="['item']" >
<li ng-repeat="item in board.lists"
dnd-draggable="item"
dnd-type="'item'"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
ng-class="{'selected': models.selected === item}"
dnd-moved="removeList($index)" >
{{item.list}}
</li>
</ul>
It all depends what are you trying to do but I wouldn't go for any class checking and DOM manipulation - that's jQuery way.
What you most likely need is to put your logic in dnd-moved - here you would splice your array and move item out of array and put it somewhere else - there in that function (removeList) you can make all necessary logic.
If that's not enough you can use this to check when element started dragging:
dnd-dragstart
or this to check when drag ended:
dnd-dragend
you even have this to check if element is dragged over another element:
dnd-dragover
and just add callback functions where you can place your logic, so there's litteraly no need for class checking. I'm not 100% sure what are you trying to do but first consider reading all documentation before you start implementing solutions: https://github.com/marceljuenemann/angular-drag-and-drop-lists

Find if ancestor has a certain CSS class

I would like to know if there is an easier way to check if an element has an ancestor with a particular class.
Consider the following HTML code:
<ul id="uniqueID" class="parentClass">
<li class="subclassA">
<div class="subclassB">
<nobr>
MyText
</nobr>
</div>
</li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
</ul>
<div>other elements in this page which I want to select</div>
Right now, I can select the element MyText by using a jQuery selector checking the href for a particular format. What I can then do is do .parent() a known number of times (4) and then check the class attribute of that particular element that I've now moved to. While this is working just fine, I am curious if there is a better way to do it, perhaps one that lets me be a bit more dynamic?
PS. There are a lot of elements that I'm selecting that'll fit this $('[href *= index.php]') format, so I want to keep those but remove the ones that fall under the categorization where they are a descendant of a member of class listclass. Currently I'm just selecting all of the elements with the selector above, then using an if statement to check through and see if it fits this condition. Again, if there is a more efficient way to do this (perhaps select these certain elements in the first place?) I would love to hear about it.
Current code:
$('[href *= "index.php"]').each(function(){
if ($(this).parent().parent().parent().parent().attr('class') != 'parentClass'){
//do things
}
});
To generalise you can use
.closest(".parentClass")
You can use closest and is:
$('[href*="index.php"]').each(function(){
if ($(this).closest('ul').is('.parentClass')) {
//do things''
}
});
if($(this).parents("ul.parentClass").length == 0){
//do something
}

JQuery not acting as it should

I am trying to make a "drop down" menu where you click a div and the sibling below it will become visible or disappear. It should be extremely simple, but it is giving me trouble for some reason.
$(".dropDownClick").click(function(){
alert($(self));
$(self).next().css("display",(node.css("display")=="inline")?"none":"inline");
});
This code returns [object Object] and then doesn't change the display css of the next sibling. After a bit of testing I found that $(self).next(); will actually break the code (if I try to do something like alert($(self).next()); the code will not execute). I am assuming this is because there is no next sibling? But my HTML would suggest otherwise:
<div class="dropDownClick"><h1>Drop</h1></div>
<div class="dropDown" style="display: none;">
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
Shouldn't the div with the class "dropDown" be selected when I call .next()?
it should be this not self, also you can use .toggle() instead of manually applying the display value
$(".dropDownClick").click(function () {
$(this).next().toggle();
});
this is a special variable, which is always available - but self/node are custom variables which has to be declared before using else it will throw a reference error
Demo: Fiddle

Detect class inside ul list, if not found delete li:first-child

I have this structure:
<ul id="#my-list">
<li><a class="class-1" href="#">Link</a></li>
<li><a class="class-2" href="#">Link</a></li>
<li><a class="class-3" href="#">Link</a></li>
</ul>
I want jquery to check if .class-1 inside #my-list exists, if not then it should delete .li (just the first one).
Basically, when the first link is deleted, the first li element should be removed as well.
$('#my-list:has(.class-1) li:first').remove()
That would of course require an ID like:
<ul id="my-list">
FIDDLE
According to your question, you'd like to do the opposite for some strange reason, and that would be :
$('#my-list:not(:has(.class-1)) li:first').remove()
but the question is, how are you deleting the anchor, and why not just delete the list item instead ?
Basically, when the first link is deleted, the first li element should be removed as well.
Sounds like you want:
$('#my-list > li').first().filter(function() {
return $(this).find('a').length === 0;
}).remove();
If you want to apply this to all li elements, not just the first one, simply omit .first().

Parallel sorting two different lists using jquery sortable

I am having very specific case where I needed to split the data into two different lists in html. Like this:
<ul id="first_list">
<li ref="1">The quick brown</li>
<li ref="2">My father works</li>
</ul>
And the second list is like:
<ul id="second_list">
<li ref="1">jumps over the lazy dog</li>
<li ref="2">at the Ministry of Defense</li>
</ul>
So as you can see I from the "ref" attribute I know which <li> element from the second list is a continuation of which <li> element from the fist list.
Now I need to enable the jQuery UI sortable() to those lists but when I reorder the first I need the second reordered too. I tried using handle but it doesn't works because it looks like the handle element needs to be inside the element which is moved but these two are at a different places in the page.
I do believe that you should have shared some of your code (what you've tried), and I'm assuming you are familiar with Sortable plugin that you are using. You should run the below code on success event of Sortable so as soon as you sort any LI, the other list will be sorted too. Anyways,
Try this:
//This line stored the LIs in a temp variable and remove it
var $cachedList = $('<div />').html($('#second_list').html());
$('#second_list > li').remove();
//This line loads up the first UL's LIs and replaces the content for each LI
//using $cachedList.
$('#second_list').html($('#first_list').html()).find('li').each(function () {
$(this).html($cachedList.find('li[ref="'+$(this).attr('ref')+'"]').html());
});
Demo: http://jsfiddle.net/AR8px/

Categories