jquery add tag around unnested text - javascript

This is a really hard question to find a title for, but here is it.
I got this HTML, that I can't change
<ul>
<li>
First part of the list
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
</li>
<li>
Second part of the list
<ul>
<li>item 3</li>
</ul>
</li>
</ul>
And I'd like to apply things to the "first part of the list" and "Second part of the list" part, but not the nested ul part, like CSS transform scaleY, and a custom Jquery onClick method.
So, the solution I'd like would be a way to JQueryly add around those.
Is this possible?
Thank you a lot

To achieve this you can filter() the li contents() to retrieve the text nodes within it, then wrap that in a span and apply the needed CSS rules. Something like this:
$('#container > ul > li').each(function() {
var foo = $(this).contents().filter(function() {
return this.nodeType == 3 && this.textContent
}).wrap('<span />');
});
#container > ul > li > span {
color: red;
display: inline-block;
transform: scaleY(2);
margin: 0 0 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul>
<li>
First part of the list
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
</li>
<li>
Second part of the list
<ul>
<li>item 3</li>
</ul>
</li>
</ul>
</div>

Related

Jquery Nested Accordion to Show Only one Level

Suppose I have a following structure:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul>
<li>Item11</li>
<li>Item12</li>
<li>Item13</li>
</ul>
</li>
This tree structure can have many levels.
Initially, I want to show following list:
Item 1
Item 2
Item 3 +
When I click on + list becomes
Item 3 -
Item 11
Item 12
Item 13
So, parent list disappears and sublist is shown.
If I click -, then everything is returned to the previous list.
Is there some jquery plugin for doing this?
Perhaps, some options in accordion?
Thanks in advance.
Used Dkouk his version to create what you need.
EDIT 1: Hide other menu items
EDIT 2: Second level menu
$(function () {
$('ul li').each(function () {
if ( $(this).find('ul').length > 0 ){
$(this).addClass('child');
}
});
$('ul li.child span').click(function() {
$(this).parent().toggleClass('open').find('ul').first().slideToggle();
$(this).parent().siblings().slideToggle();
});
});
ul {
list-style:none;
}
ul li.child span:after {
content:"+";
}
ul li.child.open span:after {
content:"-";
}
li ul { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="main">
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>
<span>Item 2</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</li>
</ul>
You can add a class to your list when it's have a sublist, and toggle the list and toggle another class for parent of list so can change the '+' to '-'.
You can as many levels, and the code will work,
I've add a span to the list have child, but so can trigger the click only at text, if you trigger click for LI list and have sublist open then will close again.
You can style the content.
Here a simple example :
$(function () {
$('ul li').each(function () {
if ( $(this).find('ul').length > 0 ){
$(this).addClass('child');
}
});
$('ul li.child span').click(function() {
$(this).toggleClass('open').parent().find('ul:first').slideToggle();
$(this).parent().siblings().slideToggle();
});
});
ul {
list-style:none;
}
ul li.child span:after {
content:"+";
}
ul li.child span.open:after {
content:"-";
}
ul li ul { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
</ul>
</li>
</ul>

CSS and jQuery universal tree menu

I want to create universal tree menu, with ul li ul. And I've made something like this using just CSS:
CSS
.category-list {
}
.category-list li ul {
display: none;
}
.category-list li:hover > ul {
display: block;
}
HTML
<ul class="category-list">
<li>
Category 1
<ul>
<li>Sub-category 1</li>
<li>Sub-cateagory 1</li>
<li>Sub-category 1</li>
</ul>
</li>
<li>
Category 2
<ul>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
</ul>
</li>
</ul>
https://jsfiddle.net/usz9ycmj/1/
--
And I want to make similar effect, but on click, so just current clicked tab displays its parent content.
Even more important for me is the ability to add and remove class on specific action:
.category-list li.current -- while is currently clicked (active)
.category-list li -- removed while different li is clicked (active)
Just, the trigger li has two different states for active and inactive. It changes the colors and arrow from closed to opened to give it a look of a tree menu - I bet You get the point.
I want the simple jquery code, if someone has time to help. feel welcome.
Here is a working code.
Please read the comments and let me know if something not clear.
// listen to the click event
var all_items = $('.category-list>li').click(function(event) {
// stop the propagation - this will abort the function when you click on the child li
event.stopPropagation();
var elm = $(this);
// remove the class from all the items
all_items.not(elm).removeClass('current');
// add class if it's not the current item
elm.toggleClass('current', !elm.is('.current'));
});
.category-list {
}
.category-list li ul {
display: none;
}
.category-list li.current > ul {
display: block;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<ul class="category-list">
<li>
Category 1
<ul>
<li>Sub-category 1</li>
<li>Sub-category 1</li>
<li>Sub-category 1</li>
</ul>
</li>
<li>
Category 2
<ul>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
</ul>
</li>
</ul>
http://jsbin.com/tocewe/edit?html,css,js

Parsing JSON with jQuery Mustache template [duplicate]

I have a list, and each item is linked, is there a way I can alternate the background colors for each item?
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
How about some lovely CSS3?
li { background: green; }
li:nth-child(odd) { background: red; }
If you want to do this purely in CSS then you'd have a class that you'd assign to each alternate list item. E.g.
<ul>
<li class="alternate">Link 1</li>
<li>Link 2</li>
<li class="alternate">Link 3</li>
<li>Link 4</li>
<li class="alternate">Link 5</li>
</ul>
If your list is dynamically generated, this task would be much easier.
If you don't want to have to manually update this content each time, you could use the jQuery library and apply a style alternately to each <li> item in your list:
<ul id="myList">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
And your jQuery code:
$(document).ready(function(){
$('#myList li:nth-child(odd)').addClass('alternate');
});
You can achieve this by adding alternating style classes to each list item
<ul>
<li class="odd">Link 1</li>
<li>Link 2</li>
<li class="odd">Link 2</li>
<li>Link 2</li>
</ul>
And then styling it like
li { backgorund:white; }
li.odd { background:silver; }
You can further automate this process with javascript (jQuery example below)
$(document).ready(function() {
$('table tbody tr:odd').addClass('odd');
});
This is set background color on even and odd li:
li:nth-child(odd) { background: #ffffff; }
li:nth-child(even) { background: #80808030; }
Try adding a pair of class attributes, say 'even' and 'odd', to alternating list elements, e.g.
<ul>
<li class="even">Link 1</li>
<li class="odd">Link 2</li>
<li class="even">Link 3</li>
<li class="odd">Link 4</li>
<li class="even">Link 5</li>
</ul>
In a <style> section of the HTML page, or in a linked stylesheet, you would define those same classes, specifying your desired background colours:
li.even { background-color: red; }
li.odd { background-color: blue; }
You might want to use a template library as your needs evolve to provide you with greater flexibility and to cut down on the typing. Why type all those list elements by hand?
Since you using standard HTML you will need to define separate class for and manual set the rows to the classes.
You can do it by specifying alternating class names on the rows. I prefer using row0 and row1, which means you can easily add them in, if the list is being built programmatically:
for ($i = 0; $i < 10; ++$i) {
echo '<tr class="row' . ($i % 2) . '">...</tr>';
}
Another way would be to use javascript. jQuery is being used in this example:
$('table tr:odd').addClass('row1');
Edit: I don't know why I gave examples using table rows... replace tr with li and table with ul and it applies to your example
If you use the jQuery solution it will work on IE8:
jQuery
$(document).ready(function(){
$('#myList li:nth-child(odd)').addClass('alternate');
});
CSS
.alternate {
background: black;
}
If you use the CSS soloution it won't work on IE8:
li:nth-child(odd) {
background: black;
}
You can by hardcoding the sequence, like so:
li, li + li + li, li + li + li + li + li {
background-color: black;
}
li + li, li + li + li + li {
background-color: white;
}

show and hide list items on hover

I have an unordered list looking like this
HTML
<div id="pop">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
</ul>
</div>
<div id="info-1></div>
<div id="info-2></div>
And when you hover over one of the items a window is displayed with some info regarding the item. I have worked this out for one item, now I wanna know how I can make this work for the entire list.
My initial thought was to create one script per each item... but that seems a bit thick considering the functionality of js.
Javascript
$(function(){
$('pop a').hover(function(){
$('#info-1').show();
},function(){
$('#info-1').hide();
});
});
So my question is of course, how can I make this script to work for all items.
I'd suggest:
$('#pop li').hover(
function() {
$('div.info').eq($(this).index()).show();
}, function() {
$('div.info').eq($(this).index()).hide();
});​
Working with slightly-changed HTML:
<div id="pop">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
</ul>
</div>
<div class="info"></div>
<div class="info"></div>
<div class="info"></div>
<div class="info"></div>
<div class="info"></div>
<div class="info"></div>
<div class="info"></div>​
JS Fiddle demo.
What I forgot to say is that this will show the .info element that corresponds to the same index as the currently hovered-over li element, so hovering the first li will show the first .info, and so on. So it's dependant on maintaining a predictable relationship between the li and the .info elements.
As an aside, it's possible to replicate this interaction using just CSS, albeit it requires a click rather than a hover event, so long as you amend the li HTML to include a link that points to the id of the relevant div:
<div id="pop">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
</ul>
</div>
<div class="info" id="info1"></div>
<div class="info" id="info2"></div>
<div class="info" id="info3"></div>
<div class="info" id="info4"></div>
<div class="info" id="info5"></div>
<div class="info" id="info6"></div>
<div class="info" id="info7"></div>​
And the CSS:
.info {
/* hides by default */
display: none;
}
.info:target {
/* shows when targeted */
display: block;
}
JS Fiddle demo. ​
Incidentally, quoting attributes is optional (though if it's an attribute that contains white-space it must be quoted), but if you quote you must have a quote at both ends of the value you're quoting: <div id="info-1></div> is not valid HTML (since the string isn't closed until the next line at the beginning of the next attribute); use: <div id="info-1"></div>.
And, further, your posted jQuery:
$(function(){
$('pop a').hover(function(){
$('#info-1').show();
},function(){
$('#info-1').hide();
});
});
This can't work, because:
the selector won't match any elements, you're trying to target an a element inside of a pop element (which, obviously, doesn't exist). What you need to do is preface the id with a # (as you do in the next line, so I'm assuming a typo there), to give: $('#pop a'). But,
there are no a elements in the #pop element, therefore no events will be, or can be, bound.
If you need to use that form, however, then a couple of adaptations can make it work:
$(function(){
$('#pop li').hover(function(){
$('#info-' + $(this).text().match(/(\d+)/)).show();
},function(){
$('#info-' + $(this).text().match(/(\d+)/)).hide();
});
});
JS Fiddle demo.
References:
eq().
hide().
hover().
index().
match().
show().
text().
try this :
$(function(){
$('#pop li').hover(function(){
$('#info-'+$(this).index()+1).show();
},function(){
$('#info-'+$(this).index()+1).hide();
});
});
you've binded an hover event on all a tags inside pop element (though you have syntax error, you should always add '#' when addressing an element by id) and you don't have them
what you''re looking for is :
$('#pop li').hover(function() {
});
Here is sample http://fiddle.jshell.net/7QmR5/
HTML:
<div id="pop">
<ul>
<li id="li1">Item 1</li>
<li id="li2">Item 2</li>
<li id="li3">Item 3</li>
</ul>
</div>
<div id="info-1" style="display:none;">info 1</div>
<div id="info-2" style="display:none;">info 2</div>
<div id="info-3" style="display:none;">info 3</div>
JavaScript:
$(function(){
$('#pop li').hover(function(){
$('#info-' + $(this).attr('id').replace('li','')).show();
},function(){
$('#info-' + $(this).attr('id').replace('li','')).hide();
});
});​
I've got an easier solution:
CSS
#info-1{
display:none;
}
ul > li:hover #info-1 {
display:block;
}
giving the li elements an id will make it easier to select them using CSS unless you want to use pseudo I believe it's called.
Or the jQuery if needed:
$('li:eq[0]','#pop').hover(function(){
$('info-1').show();
});

JQuery - Attach (duplicate, clone) li and put it above a li

Is it possible to clone a specific < li> and put it above an other specific < li>?
Any clue would help me..?
HTML
<div id="main">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
Pseudo Javascript (JQuery)
$('#main ul li:eq(3)').duplicateAndPutAbove('#main ul li:eq(2)');
HTML Result
<div id="main">
<ul>
<li>Item 1</li>
<li>Item 3</li> <!-- Item 3 was duplicated (or cloned) and then putted ABOVE Item 2 -->
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
You were really close, you wanted clone and insertBefore (and remember that eq is zero-based):
$('#main ul li:eq(2)').clone().insertBefore('#main ul li:eq(1)');
Live example
$('#main ul li:eq(3)').clone().insertBefore('#main ul li:eq(2)');
Demo: http://jsfiddle.net/karim79/8LpuN/
var elem = $('li').contains('3').clone(); // make a copy
$('li').contains('Item 3').before(elem); // insert before the cloned element
$('#main ul li:eq(3)').clone().insertBefore('#main ul li:eq(2)');

Categories