I'm trying to break up an unordered list containing eight items into two lists, each containing four items.
I figured that .inserting closing and opening tags after the fourth list item should cut it:
if(i == 3) {
$(li).insert({
after: "</ul><ul>"
});
}
But Prototype gives me the <ul></ul> in the opposite order.
<ul>
<li />
<li />
<li />
<li />
<ul></ul>
<li />
<li />
<li />
<li />
</ul>
Is there a simple answer to this one?
Here's how I would do it
Html:
<div id="list">
<ul id="original">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</div>
Javascript:
var ul = new Element('ul');
$$('#original li').each(function(li, index) {
if (index % 3 == 0 && index > 0) {
$('list').insert({
bottom: ul
});
ul = new Element('ul');
}
ul.insert({
bottom: li
});
});
$('list').insert({
bottom: ul
});
$('original').remove();
Look at a live example
Use JavaScript's MOD operator to see when you are on the first or 4th row. If you are, create the UL element and then add the LIs to this element.
Something like:
if ( i % 4 == 0 ) {
currentUl = new Element('ul');
$('li').appendChild(currentUl);
}
It doesn't work like that.
Create a new UL, and move the items to that List:
function moveToOtherList(item){
var myList = item.up('ul');
var next = myList.next('ul');
if(!next){
next = new Element('ul',{style:"margin-top:20px;"});
myList.insert({after:next});
}
next.insert({bottom:item});
}
$$('ul li').each(function(item, index){
if(index > 3){
moveToOtherList(item);
}
});
See this jsfiddle for a working example
I dont know in Prototype but in Jquery you can try this http://jsfiddle.net/nxapS/7/
Related
I have 8 li elements with each having value from 1 to 8.
<ul>
<li>1</li>
<li class="even">2</li>
<li>3</li>
<li class="even">4</li>
<li>5</li>
<li class="even">6</li>
<li>7</li>
<li class="even">8</li>
</ul>
I want to insert li with text 'I am above x' above every li with even value. The desired li should look like
<ul>
<li>1</li>
<li>This is above 2</li>
<li class="even">2</li>
<li>3</li>
<li>This is above 4</li>
<li class="even">4</li>
<li>5</li>
<li>This is above 6</li>
<li class="even">6</li>
<li>7</li>
<li>This is above 8</li>
<li class="even">8</li>
</ul>
This can't be hardcoded as i have simplified the problem. Actually i want to dynamically add html above specific li elements.
I tried using .insertBefore() but this is not working.
("<li>x</li>").insertBefore$('#listing li.even');
You can use :nth-child() selector like this.
$('li:nth-child(even)').each(function() {
var num = $(this).text();
$(this).before('<li> This is before '+ num +'</li>');
})
$('li:nth-child(even)').each(function() {
var num = $(this).text();
$(this).before('<li> This is before ' + num + '</li>');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>1</li>
<li class="even">2</li>
<li>3</li>
<li class="even">4</li>
<li>5</li>
<li class="even">6</li>
<li>7</li>
<li class="even">8</li>
</ul>
Use :even selector that select element has even index and use .before( function ) to insert html before selected element. .before() is a good alternative instead .each() if you want to insert html in loop.
$("li:gt(0):even").before(function(i, text){
return "<li>This is above " + text + "</li>";
});
$("li:gt(0):even").before(function(i, text){
return "<li>This is above " + text + "</li>";
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>1</li>
<li class="even">2</li>
<li>3</li>
<li class="even">4</li>
<li>5</li>
<li class="even">6</li>
<li>7</li>
<li class="even">8</li>
</ul>
Yikes, it's because the syntax is way off.
$("<li>x</li>").insertBefore($('#listing li.even'));
The $ in the beginning is just a shorthand for jQuery's wrapping function, which returns a jQuery object. Without it, you are trying to call insertBefore on a string value "<li>x</li>". Strings don't have the insertBefore function, jQuery objects do.
Also, you have insertBefore$('...'). insertBefore is a function, insertBefore$ is not. You are trying to call insertBefore$ on a string, but what you really want is to call insertBefore on a jQuery object.
Also, technically in the provided fiddle #listing doesn't exist, but I kept in it because I assume it exists on the page in question?
$(document).ready(function () {
$.each($("#listid").find("li:odd"), function () {
$(this).before("<li>This is above " + $(this).text() + "</li>");
});
});
Working code: https://jsfiddle.net/n3tzf2pd/7/
try this
<html>
<script>
function generate(num) {
var text = "<ul>";
for (var i = 0; i < num; i++) {
text += "<li>text: " + i + "</li>";
}
text += "<ul>";
var div = document.getElementById("your_div");
div.innerHTML = text;
}
</script>
<body>
<div id="your_div"></div>
<input type="button" onclick="generate(8)" value="Generate" />
</body>
</html>
I'm trying to get all visible elements from list, but I can't find the way.
I have list
<ul id="posts">
<li style="display:none">1</li>
<li style="display:none">2</li>
<li>3</li>
<li style="display:none">4</li>
<li>5</li>
<li style="display:none">6</li>
<li>7</li>
<li>8</li>
</ul>
and I want to get every second visible element and add class "visible" to it.
I want this result
<ul id="posts">
<li style="display:none">1</li>
<li style="display:none">2</li>
<li>3</li>
<li style="display:none">4</li>
<li class="visible">5</li>
<li style="display:none">6</li>
<li>7</li>
<li class="visible">8</li>
</ul>
I tried something like this
var jQuerylistItems = jQuery('#posts').children('li');
jQuerylistItems.filter(':visible').addClass('visible');
and it works, but not right, somethimes add class, sometimes not, I'm not sure why.
Can somebody help me please?
Thanks
I would suggest using something like the following:
jQuery('#posts > li:visible:odd').addClass('visible');
Checkout out the demo here.
you can try .each();
$(document).ready(function(){
$('ul > li').each(function(){
if($(this).is(':visible')){
$(this).addClass('visible');
}
});
});
Demo
Here's solution for you. And also demo on fiddle
(function() {
'use-strict';
var el = document.getElementsByTagName('li');
for(var i=0;i<el.length;i++) {
if(!el[i].style.display && i%2 !== 0) {
el[i].className = 'visible';
}
}
}());
Modify the addClass() to use a callback and the first argument of callback is index
jQuerylistItems.filter(':visible').addClass(function(i) {
return i % 2 == 1 ? 'visible' : null;
});
My understanding is only add this class to every other visible element.
You will also need to remove this class before running it again which could be the part of the problem you are encountering
DEMO
Here's one solution: http://jsfiddle.net/5op0wzv9/.
$('ul > li:visible').each(function(index){
$(this).addClass(index % 2 === 1 ? "visible" : "");
});
I dont know if this is what you want, but here you go!!. Hope it helps.
<!DOCTYPE html>
<html lang = 'es'>
<head>
<title> MY TEST </title>
<meta charset = 'utf-8'>
</head>
<body>
<ul id="posts">
<li style="display:none">1</li>
<li style="display:none">2</li>
<li>3</li>
<li style="display:none">4</li>
<li>5</li>
<li style="display:none">6</li>
<li>7</li>
<li>8</li>
</ul>
<script>
var visibleElements = [];
var allListElements = document.getElementsByTagName('li'); // Get the reference to al the "li" elements
var index;
// Check for each element in array if his display its diferent to "none", if true, add that element to the array "visibleElements"
for (index = 0; index < allListElements.length; index++){
if(allListElements[index].style.display != 'none'){
visibleElements.push(allListElements[index]);
}
};
//Adding the class
for (var index2 in visibleElements){
visibleElements[index2].className = 'visible';
console.log('VISIBLE') // Check if adding the class name is working, if console shows 4 "VISIBLE" then its OK.
}
</script>
</body>
</html>
I have a pagination bar and it will switch to the next button if you click the "next" or "prev" arrow buttons.
I wrote some code to stay on the current "page" number if the next item in the list is ".next" or ".prev", but it is not working.
What am I missing?
$(document).ready(function() {
var pageItem = $(".pagination li").not(".prev,.next");
var prev = $(".pagination li.prev");
var next = $(".pagination li.next");
pageItem.click(function() {
$('li.active').removeClass("active");
$(this).addClass("active");
});
// stay on current button if next or prev button is ".next" or ".prev"
next.click(function() {
if($('li.active').next() != next) {
$('li.active').removeClass('active').next().addClass('active');
}
});
prev.click(function() {
if($('li.active').prev() != prev) {
$('li.active').removeClass('active').prev().addClass('active');
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<nav>
<ul class="pagination">
<li class="prev">
<span>«</span>
</li>
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li class="next">
<span>»</span>
</li>
</ul>
</nav>
jQuery selectors return an Array object, objects cannot be deemed equal unless they are derived from each other.
i.e.
var a = []
var b = []
console.log(a==b); //would output false
If you changed you code to select the item in the array you would get the actual DOM node
$('li.active').next()[0] != next[0]
All you need to check the class name, Please check below updated code
$(document).ready(function() {
var pageItem = $(".pagination li").not(".prev,.next");
var prev = $(".pagination li.prev");
var next = $(".pagination li.next");
pageItem.click(function() {
$('li.active').removeClass("active");
$(this).addClass("active");
});
// stay on current button if next or prev button is ".next" or ".prev"
next.click(function() {
if($('li.active').next().attr('class') != 'next') {
$('li.active').removeClass('active').next().addClass('active');
}
});
prev.click(function() {
if($('li.active').prev().attr('class') != 'prev') {
$('li.active').removeClass('active').prev().addClass('active');
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<nav>
<ul class="pagination">
<li class="prev">
<span>«</span>
</li>
<li class="active">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li class="next">
<span>»</span>
</li>
</ul>
</nav>
I have the following list:
<ul>
<li class="item">One</li>
<li class="item">Two</li>
<li class="item">Three
<ul>
<li class="item">Something Original</li>
<li class="item selected">Something</li>
</ul>
</li>
<li>Four
<ul>
<li class="item">I want this selected next</li>
<li class="item">Good</li>
</ul>
</li>
</ul>
Using jQuery, how do I find the next li with the class="item" since it is wrapped in a different container. Obviously I cannot do $(".selected").next(".item") so how else can I do it?
JSFiddle: http://jsfiddle.net/q3f6v7zz/
Since the li elements are nested and you know that you want the next appearing li with a particular class, you can use .index() and do something like this
var $li = $('.item'); // <--- get the list of all lis with class .item
var index = $li.index($('.selected')); // <--- find the index of the one with .selected amongst all the lis
console.log($li.eq(index+1).html()); // <--- index+1 because you need the next appearing li after selected
If you want to move the selected class on keydown something like this should do
var $li = $('.item');
$(document).on('keydown', function(e) {
if (e.keyCode == 40) {
var index = $li.index($('.selected'));
$li.eq(index).removeClass('selected');
index = (index+1) % $li.length; // <--- to rotate the values from 0 to count of li.item elements
$li.eq(index).addClass('selected');
}
});
var $li = $('.item');
$(document).on('keydown', function(e) {
if (e.keyCode == 40) {
var index = $li.index($('.selected'));
$li.eq(index).removeClass('selected');
index = (index+1) % $li.length;
$li.eq(index).addClass('selected');
}
});
.selected {
background: green;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li class="item">One</li>
<li class="item">Two</li>
<li>Three
<ul>
<li class="item">Something</li>
<li class="item selected">Something Else</li>
</ul>
</li>
<li>Four
<ul>
<li class="item">I want this selected next</li>
<li class="item">Good</li>
</ul>
</li>
</ul>
You can get the index of the selected element within all lis, and then increment that index to get the next one.
$("ul").on("click", "li.item.selected", function() {
var all_li = $("li.item");
var selected_index = all_li.index(this);
var next_li = all_li.eq((selected_index + 1) % all_li.length);
$(this).removeClass("selected");
next_li.addClass("selected");
});
.item.selected {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="item">One</li>
<li class="item">Two</li>
<li class="item">Three
<ul>
<li class="item selected">Something</li>
</ul>
</li>
<li>Four
<ul>
<li class="item">I want this selected next</li>
<li class="item">Good</li>
</ul>
</li>
</ul>
I used the modulus so it will wrap around at the end.
Not sure what you are exactly looking for but you can use $(Element").parent().parent().find("li");
So in other words .parent() may be what you are looking for there is also .sibling() to find or you may want $('li').closest('ul').find('li')
which will go up the tree to find the nearest ul to the one you are looking for
https://api.jquery.com/closest/
You may also use:
Vanilla JS to do something similar to what was discussed by others with $index if it makes more sense to you:
Again this isn't as efficient but that is basically what JQuery is doing:
var myLis = document.getElementsByTagName('li');
var wantedIndex;
for(var i = 0;i<myLis.length; i++){
if(myLis[i].className === "active"){
wantedIndex = i+1; //gets the li which is next when selecting all lis
}
}
I have a list showing in html like this:
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>...</li>
</ul>
Now, I added for each 2nd line a background color using this jquery:
$("ul li").each(function(index) {
if (index % 2 == 0) {
$(this).addClass("second-line");
}
});
BUT, each list item can be filtered to just view for the user currently logged in. So some lines will be hidden if I would filter the list. But after filtering the list, the jQuery to make each 2nd line is messed up.
How can I make that work?
I tried this:
$(".button").click(function() {
$("ul li").each(function(index) {
var uid = $(this).attr("data-uid");
var tuid = $(this).attr("data-tuid");
if (uid != tuid) {
$(this).hide(500);
}
});
$("ul li").each(function(index) {
if (index % 2 != 0) {
$(this).removeClass("second-line");
}
});
});
But no success.
you can use $( "ul li:nth-child(2)" ).addClass("second-line"); for the second elemnt.
You should try the :odd selector. With this one, you can select all the odd items (= 2nd, 4th,...). More info here: https://api.jquery.com/odd-selector/
you can make it with css.
like:
ul:nth-child(even){
background-color: #00ffff;
}
Hope it will helps you
ul li:nth-child(even) {
color: red;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
may this will work for you
$("ul li:even").each(function(index) {
$(this).removeClass("second-line");
});
jquery even