jQuery closest li with a class doesn't work - javascript

I have menu (list of categories), level-0 li has class ".cat_cat_h", level-1 .cat_par_c"
HTML:
<ul class="text-links">
<li class="cat_cat_h level-0">Item 1</li>
<li class="cat_cat_h level-0">Item 2</li>
<li class="cat_cat_h level-0 active">Item 3</li>
<li class="cat_par_c level-1" style="display: none;">Item 4</li>
<li class="cat_par_c level-1" style="display: none;">Item 5</li>
<li class="cat_par_c level-1" style="display: none;">Item 6</li>
<li class="cat_cat_h level-0">Item 7</li>
<li class="cat_cat_h level-0">Item 8</li>
<li class="cat_cat_h level-0">Item 9</li>
<li class="cat_cat_h level-0">Item 2</li>
<li class="cat_par_c level-1" style="display: none;">Item 7</li>
<li class="cat_par_c level-1" style="display: none;">Item 8</li>
<li class="cat_par_c level-1" style="display: none;">Item 9</li>
</ul>
I would like to show() only level-1 elements that go right after .level-0.active (item 4, item 5, item 6).
UPDATE
Final solution:
$(document).ready(function(){
$( ".level-0.active" ).nextUntil( ".level-0" ).show();
});

Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
Source
That means the closest() function works in one direction. if you want to go to the parent <ul> and the back to another <li> you have to call the parent() function first, like this:
$(document).ready(function(){
$(".cat_cat_h").parent('ul').find(".cat_par_c").show();
});
edit after your edit:
If you want the previous and the next element of you selected element try this:
$(document).ready(function(){
$( ".level-0.active" ).prev().show();
$( ".level-0.active" ).next().show();
});

To be responsive to Paulchenkiller, I will amplify my answer.
Fluency in any language, spoken (English, Spanish, Italian, French, German, etc) or written (html, css, javascript, c++, pascal, basic, etc) requires the ability to express a certain concept, idea or task in a variety of different ways.
I will attempt to do so with this particular issue in as many ways that this particular noob can think of.
jQuery selectors - this has been nicely expounded on above, and the only comment I might make is the trivial downside in the use of jQuery in terms of its load time (microseconds to milliseconds), and perhaps slightly longer to run than native js (microseconds).
CSS classes - One way to handle this is the use of additional css classes - adding a class, say "li456" that is an "empty" class in the sense that it contains no CSS styling, and is only used to identify a particular line or lines of code. Here is a FIDDLE as an example. It's a bit inefficient in the sense that it can be difficult to follow the code with so many classes attached to a line of html, and needing to look up an additional class in the section or even an attached style sheet.
$(".li456").show();
CSS ids - Even more burdensome, since you can only use an id once on a page, and in this particular case, therefore need three ids. The same applies to ids as to classes, only worse, you have to look up three times the number of ids as classes - since one class can be associated with multiple html lines on a given page. Here is a FIDDLE that shows an example of the use of ids .
$("#li4, #li5, #li6").show();
A variant of CSS is the concept of pseudo classes which are beautifully explained by the experts at CSS-Tricks where they have a nice review of these flexible and powerful methods (http://css-tricks.com/pseudo-class-selectors/). The :lt(x) selects the first x elements of type. Here is the FIDDLE. The :lt() pseudo class is particular to jquery and not a part of the CSS standard.
$(".text-links .cat_par_c:lt(3)").show();
Pure javascript is also a possibility, but in this particular case you would have to add an id to the three elements in question. Here is the FIDDLE.
document.getElementById('li4').style.display='block';
document.getElementById('li5').style.display='block';
document.getElementById('li6').style.display='block';
Pure javascript can be used to select on the class name, and return an array that can be parsed by [n]. This FIDDLE shows an example of a brute-force method. This FIDDLE uses a for loop to go through three elements.
document.getElementsByClassName('cat_par_c')[n].style.display='block';
Then we move to "display" which can be handled with jQuery .show, .css('display', 'block') and javascript .style.display='block'. This FIDDLE demonstrates these methods.
$('.cat_par_c:eq(0)').show();
$('.cat_par_c:eq(1)').css('display', 'block');
document.getElementsByClassName('cat_par_c')[2].style.display='block';
And I'll bet there are many more ways...

Related

targeting a li with javascript without a ID

I have a mobile nav, that looks like this
<ul id="mobile-menu" class="menu>
<li class="normal-link">link-1</li>
<li class="dropdown-link">link-2
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="dropdown-link">link-3
<ul class="submenu">
<li class="link-of-dropdown>blabla</li>
<li class="link-of-dropdown>blabla</li>
</ul>
</li>
<li class="normal-link">link-1</li>
</ul>
I cant change the html/wordpress generated code, but I can add css and javascript. So is there a way for me to get next to the dropdown-link's a image that will let the submenu free. if the image is pushed the image will change. if pushed again it will go back to the normal image and the dropdown dissappears again?
I am mostly looking for answer for the problem with of javascript on the dropdown link's but just so you know what i want to do with it.
This question is so very, very vague. But I guess you're looking for the nth-child() selector.
See the docs here for more information. Target your 'mobile-menu' ul, and use nth-child to select the li elements within.
My big question would be, why can't you change the HTML? If it's Wordpress, you can modify the template to change the HTML.
You question is not really clear but if you want to retrieve an element without using id, first you may use their classes
var myClass = document.getElementsByClassName("classname"); //returns a nodeList like array
myClass[0] //first element with "classname"
You may also use tag names
var divs = document.getElementsByTagName("div");
divs[2] //third "divs"
You may also use querySelectorAll, this works pretty much like CSS selector and also returns a nodeList
var qs = document.querySelectorAll(".class");
I hope this helps
You could add a class and use the Jquery class selector: $(".class-name") to target a specific <li>

finding elements that are under or above div

So I have a pretty strange question here. How do you find out if there are any other div elements under or above a specific div element. For my project that I'm working on right now, I have a bunch of smaller divs underneeth and i want a selector that allows the users to select any number of those divs. The way I thought of was to use a resizeable div that can be dragged around as the selector div on z-index of n+1 and the rest of the divs that are to be selected is on z-index of n. To do this I will use a combination of:
http://www.w3schools.com/cssref/css3_pr_resize.asp
and
https://jqueryui.com/draggable/
which lets me make a draggable and resizeable object div that I can use to select the divs underneath. Is there some elegant way of doing this or do I just have to go and do this the hard way by finding out it's location and manually find all the divs that are under it.
Also if there's another way to do this more elegantly i'd be all ears.
Thanks
If you are using jQuery UI, use the UI's Selectable.
From the source of the example in the link:
<ol id="selectable">
<li class="ui-state-default">1</li>
<li class="ui-state-default">2</li>
<li class="ui-state-default">3</li>
<li class="ui-state-default">4</li>
<li class="ui-state-default">5</li>
<li class="ui-state-default">6</li>
<li class="ui-state-default">7</li>
<li class="ui-state-default">8</li>
<li class="ui-state-default">9</li>
<li class="ui-state-default">10</li>
<li class="ui-state-default">11</li>
<li class="ui-state-default">12</li>
</ol>
<script>
$( "#selectable" ).selectable();
</script>
var parent = jQuery(ld).parent();
var child = jQuery(id).children();
I hope that it will be a correct solution.

Which are the best way to go through a series of elements with jquery?

I have a set of elements
<div id="lista">
<ul>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
</ul>
</div>
Then i'm using jquery, it's better do this?:
$("#lista li").each(function(){ //something };
or this?:
$(".seto").each(function(){ //something });
Thanks.
You can read about selector optimizatoin here:
https://learn.jquery.com/performance/optimize-selectors/.
The $("#lista").children('li') will be the fastes.
But in your case performance is not so important, so you can use whatever you prefer.
Performance will not be an issue I think.
Your jquery should reflect your intent of the code.
Depending of your want to apply styling, I would choose the class version.
If you want to do some post-processing on specific business objects, I would use the ID version.
Having said that, I think you should use the class version, and make sure that the business objects have the correct classes to attach the styling to. Including jQuery functions.
It depends upon your case
Case 1:
For exxample ur case is like this means
<div id="lista">
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<li class="seto">Element 1</li>
<ol class="seto">diff Element 1<ol>
</div>
If you want to go through list of all "seto" contain class elements
Then u go for second method. Or else you can use first method

Sitemap tree indentation visualization

For a sitemap page I have the ordered text and the associated 'level' of how far the page is in the tree.
Right now we have the most simplistic indented look using CSS margins and we want it to look more funky.
Here is the sample code and a link to a test page:
HTML:
<div class='sitemapItem'>
<a href="#">
<div class='sitemapLevelX'>FOO</div>
</a>
</div>
CSS:
.sitemapLevelX{
margin-left:Ypx;
}
Sample code can be found here:
http://jsfiddle.net/m77TR/1/
I include the following image to get an idea what I'm aiming for:
Is it possible to do relatively simply in CSS? Or do I need to sprinkle some javascript on top?
You could simply achieve this structure using a nested ul:
<ul>
<li>level 1</li>
<li>level 1</li>
<li>level 1 with sub
<ul>
<li>level 2</li>
<li>level 2</li>
</ul>
</li>
</ul>
This way you can easily define this kind of subtree structure in HTML. After this you can change the styling in CSS to fit your needs.
A demo for your desired layout can be seen here: http://jsfiddle.net/N4JH2/ and a tutorial on how to get this done here: http://www.csscody.com/css/css-sitemap-design-tutorial/594/
The closest css property I can think of is 'quotes', which allows you to define different symbols for different levels of quotes.

How do I connect multiple sortable lists to each other in jQuery UI?

I'm new to jQuery, and I'm totally struggling with using jQuery UI's sortable.
I'm trying to put together a page to facilitate grouping and ordering of items.
My page has a list of groups, and each group contains a list of items. I want to allow users to be able to do the following:
Reorder the groups
Reorder the items within the groups
Move the items between the groups
The first two requirements are no problem. I'm able to sort them just fine. The problem comes in with the third requirement. I just can't connect those lists to each other. Some code might help. Here's the markup.
<ul id="groupsList" class="groupsList">
<li id="group1" class="group">Group 1
<ul id="groupItems1" class="itemsList">
<li id="item1-1" class="item">Item 1.1</li>
<li id="item1-2" class="item">Item 1.2</li>
</ul>
</li>
<li id="group2" class="group">Group 2
<ul id="groupItems2" class="itemsList">
<li id="item2-1" class="item">Item 2.1</li>
<li id="item2-2" class="item">Item 2.2</li>
</ul>
</li>
<li id="group3" class="group">Group 3
<ul id="groupItems3" class="itemsList">
<li id="item3-1" class="item">Item 3.1</li>
<li id="item3-2" class="item">Item 3.2</li>
</ul>
</li>
</ul>
I was able to sort the lists by putting $('#groupsList').sortable({}); and $('.itemsList').sortable({}); in the document ready function. I tried using the connectWith option for sortable to make it work, but I failed spectacularly. What I'd like to do is have the every groupItemsX list connected to every groupItemsX list but itself. How should I do that?
I was thinking I needed to specifically not connect a list to itself less there be some sort of circular reference. Granted, I'm not working with Excel, but it seemed like that could cause some sort of never ending recursion that would cause a stack overflow or something. Hmm. Sorry for the pun. Couldn't help myself.
Anyway, I was trying to do something like this, and it wasn't working:
$('.groupsList').sortable(); // worked great
$('.groupsList').each( function () {
$(this).sortable( {
connectWith: ['.groupsList':not('#'+ $(this).attr('id') )];
});
});
I'm sure I've completely mangled the syntax there, and I suppose that's the reason I had to ask the question in the first place. Is it even necessary or helpful performance-wise to filter the current item out of the list?
Both of the answers provided by Adam and JimmyP worked in IE (although they behave really oddly in FireFox, overwriting list items when you try to re-sort). I'll accept one of your answers and vote on the other, but if you have ideas/ suggestions about the filtering, I'd like to hear it.
Can you include the syntax you used for connectWith? Did you place the list of other groups inside brackets(even if it's a selector)? That is:
...sortable({connectWith:['.group'], ... }
This should work:
$('#groupsList').sortable();
$('.itemsList').sortable({
connectWith: $('.itemsList')
});
$(function() {
$( "#groupItems1, #groupItems2, #groupItems3" ).sortable({
connectWith: ".itemsList"
}).disableSelection();
});
This will go all fine for you! doing the same here for me. NO change required in your HTML.

Categories

Resources