How can I remove and append element li? - javascript

My html code like this :
<ul class="list">
<li id="thumb-view-1">view 1</li>
<li id="thumb-view-2">view 2</li>
<li id="thumb-upload-3">upload 3</li>
<li id="thumb-view-4">view 4</li>
<li id="thumb-view-5">view 5</li>
</ul>
<button id="test">Test</button>
My javascript code like this :
<script type="text/javascript">
$('#test').on("click", function(e){
var a = 3;
for(var i = 1; i <= 5; i++) {
if(i == a) {
$('#thumb-upload-'+i).remove();
var res = '<li id="thumb-view-'+i+'">view '+i+'</li>';
$('#thumb-view-'+(i-1)).after(res);
}
}
});
</script>
Demo : https://jsfiddle.net/oscar11/eb114sak/
It works
But my case is dynamic. var a has value between 1 - 5. So var a can have value 1 or 2 or 3 or 4 or 5
While ul tag has 5 li tag. And 5 li tag can have different id type
So in addition to the tag li above, I give an example of another form
Like this :
<ul class="list">
<li id="thumb-upload-1">upload 1</li>
<li id="thumb-view-2">view 2</li>
<li id="thumb-view-3">view 3</li>
<li id="thumb-view-4">view 4</li>
<li id="thumb-view-5">view 5</li>
</ul>
etc
If like that, the result still wrong
It seems it should call the li element based on a
So if a = 3 then the third li tag is deleted and append
But, I'm still confused
How can I do it?

Instead of remove / append, try replaceWith:
$('#test').on("click", function(e){
var a = 3;
for(var i = 1; i <= 5; i++) {
if(i == a) {
var res = '<li id="thumb-view-'+i+'">view '+i+'</li>';
$('#thumb-upload-'+i).replaceWith(res);
}
}
});
This will only replace matching #thumb-upload- elements, so it will handle your dynamic cases.

A simple solution could be to use replaceWith and index as
var index = $( "ul.list" ).index( $("li[id^='thumb-upload']") );
This will get the index of li whose class starts with thumb-upload within your unordered list
$("li[id^='thumb-upload']").replaceWith('<li id="thumb-view-'+index +'">view '+index +'</li>';)
And the above statement will replace that list item with your custom HTML
Another simple solution is to just change the ID as I don't see other changes as
$("li[id^='thumb-upload']").attr('id', $("li[id^='thumb-upload']").attr('id').replace('upload','view'));

Related

How to change button text to innerHTML of clicked list item

I've been searching but all i find are JQuery answers, i'm looking for a vanilla JS solution.
When a list-item gets clicked, i want the button text to change into the innerHTML of that clicked li.
I'm getting close, but somehow the current variable only returns the innerHTML of the last list-item.
So what do I need to change to get the innerHTML of the clicked li as button text?
JS-Fiddle here
var clickHandler = function() {
document.getElementById('dropbtn').innerHTML = current.innerHTML;
};
var dropdown = document.getElementById('dropdown');
var filterItem = dropdown.getElementsByTagName('LI')
for (var i = 0; i < filterItem.length; i++) {
var current = filterItem[i];
current.addEventListener('click', clickHandler, false);
}
<div class="dropdown">
<a id="dropbtn">Menu</a>
<ul id="dropdown" class="dropdown-content">
<li>ALL</li>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</div>
I cut out the css of this dropdown to keep things clear.
As stated in the comments change
document.getElementById('dropbtn').innerHTML = current.innerHTML;
To
document.getElementById('dropbtn').innerHTML = event.target.innerHTML;
var clickHandler = function() {
document.getElementById('dropbtn').innerHTML = event.target.innerHTML;
};
var dropdown = document.getElementById('dropdown');
var filterItem = dropdown.getElementsByTagName('LI')
for (var i = 0; i < filterItem.length; i++) {
var current = filterItem[i];
current.addEventListener('click', clickHandler, false);
}
<div class="dropdown">
<a id="dropbtn">Menu</a>
<ul id="dropdown" class="dropdown-content">
<li>ALL</li>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</div>
You are you listening to an click event, You can use that event to identify on where that event was fired.
var clickHandler = function(e) {
document.getElementById('dropbtn').innerHTML = e.target.innerHTML
};
var dropdown = document.getElementById('dropdown');
var filterItem = dropdown.getElementsByTagName('li')
console.log(filterItem)
for (var i = 0; i < filterItem.length; i++) {
var current = filterItem[i];
current.addEventListener('click', clickHandler, false);
}

Using link to remove list items from page using HTML5 and Javascript

I am trying to create a link that will remove two list items from an ul that are above the link. I am new at this and appreciate any help!
The question is pretty vague, but this is how I would achieve something like this in JavaScript with a link.
HTML:
<ul id="my_list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
click to remove item
JavaScript:
function deleteItems() {
var item_list = document.querySelectorAll("ul#my_list li");
if (item_list.length >= 2) {
item_list[0].parentNode.removeChild(item_list[0]);
item_list[1].parentNode.removeChild(item_list[1]);
} else if (item_list.length == 1) {
item_list[0].parentNode.removeChild(item_list[0]);
}
}
var delete_link = document.getElementById('delete_items');
delete_link.onclick = deleteItems;
Codepen link here.

Fade in/out list of DOM elements one at a time

I've got a web page with a large list of hidden li elements that I'd like to endlessly loop over and display on a small visible list of 5 li elements. I'm currently using a recursive method that calls itself with the next li element after each update which works fine to fade in/out each visible li one at a time forever. However once I try to change the html in the visible li to the html in the hidden li that I'm looping over all hell breaks loose. All 5 visible li's get set to the first 5 hidden li's and fade in/out all at once. Then there is a long pause, the page freezes for a bit and eventually all 5 visible li's will fade in/out again and still be set to the first 5 hidden li's. It's like once I try to change the html all of a sudden the entire looping happens all at once and I can't perceive why that would be the case.
$(function () {
fade($("#all-donors").first(), 1);
});
function fade(elem, curItem) {
var curElement = $("#donor" + curItem);
//curElement.html(elem.html()); //This line breaks it
curElement.fadeOut(1000).fadeIn(1000, function () {
curItem++;
if (curItem > 5) {
curItem = 1;
}
// If we're not on the last <li>
if (elem.next().length > 0) {
// Call fade on the next <li>
fade(elem.next(), curItem);
}
else {
// Else go back to the start
fade(elem.siblings(':first'), curItem);
}
});
}
To Loop LI's from just 1 <UL> element, and to loop <LI> tags from 2 <UL> elements, using the first UL as a visible UL and the 2nd UL as the looper UL
1ST APPROACH
JSFIDDLE FINAL RESULT HERE
Fade in, only after fading out is complete. And use class to hide all li elements except the first li initially and no need to send the curItem parameter to the function, which could only mess things up, just send the .next or :first element to the function instead. And no need to use .length > 0, .length is good enough.
$(document).ready(function() {
myFunc($(".show"));
});
function myFunc(oEle)
{
oEle.fadeOut('slow', function(){
if (oEle.next().length)
{
oEle.next().fadeIn('slow', function(){
myFunc(oEle.next());
});
}
else
{
oEle.siblings(":first").fadeIn('slow', function(){
myFunc(oEle.siblings(":first"));
});
}
});
}
HTML:
<ul class="listitem">
<li class="show">Test 1</li>
<li class="hidden">Test 2</li>
<li class="hidden">Test 3</li>
<li class="hidden">Test 4</li>
</ul>
2ND APPROACH, and answer to your question!
JSFIDDLE FINAL RESULT HERE
jQUERY:
var curIndex = 0,
nextIndex = 0;
$(document).ready(function() {
myFunc($(".show").children().eq(curIndex), $(".hidden").children().eq(nextIndex));
});
function myFunc(curLI, nextLI)
{
curLI.fadeOut('slow', function(){
$(this).html(nextLI.html()).fadeIn('slow', function() {
curIndex = curLI.next().length ? ++curIndex : 0;
nextIndex = nextLI.next().length ? ++nextIndex : 0;
myFunc($(".show").children("li").eq(curIndex), $(".hidden").children("li").eq(nextIndex));
});
});
}
HTML STRUCTURE:
<ul class="listitem show">
<li>Blah 1</li>
<li>Blah 2</li>
<li>Blah 3</li>
<li>Blah 4</li>
<li>Blah 5</li>
</ul>
<ul class="listitem hidden">
<li>Test 1</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
<li>Test 5</li>
<li>Test 6</li>
<li>Test 7</li>
<li>Test 8</li>
<li>Test 9</li>
<li>Test 10</li>
<li>Test 11</li>
<li>Test 12</li>
<li>Test 13</li>
<li>Test 14</li>
</ul>
CSS:
.listitem {
list-style-type: none;
list-style: none;
}
ul.hidden li {
display: none;
}
Sorry, guess I didn't fully understand what you were asking for exactly. Well, hopefully this helps someone, if not you.
Here, I think this is what you're looking for.
It can be changed for your needs, but it's the basic thing working.
JSFiddle (updated): http://jsfiddle.net/Ut86V/4/
HTML:
<ul class="list1">
<li>blahxx</li>
<li>blahxxx</li>
<li>blahxxxx</li>
<li>blahxxxxx</li>
<li>blahxxxxxx</li>
</ul>
<ul class="list2">
<li>blah1</li>
<li>blah2</li>
<li>blah3</li>
<li>blah4</li>
<li>blah5</li>
<li>blah6</li>
<li>blah7</li>
<li>blah8</li>
<li>blah9</li>
<li>blah0</li>
<li>blah11</li>
<li>blah12</li>
<li>blah13</li>
<li>blah14</li>
<li>blah15</li>
<li>....</li>
</ul>
Javascript:
function popList( speed ) {
speed = speed || 2000;
var $list1 = $('.list1 li');
var $list2 = $('.list2 li');
var item = 0;
var source = 0;
for( i=0; i<5; i++ ) {
$list1.eq( i ).html( $list2.eq( i ).html() );
source = i+1;
}
var replaceContent = function() {
$list1
.eq( item )
.delay( speed/2 )
.animate(
{ opacity: 0 },
speed/4,
function() {
var content = $list2.eq( source ).html();
$(this)
.html( content )
.animate(
{ opacity: 1 },
speed/4
);
item = ( item >= 4 ) ? 0 : item+1;
source = ( source >= $list2.length-1 ) ? 0 : source+1;
replaceContent();
}
);
};
replaceContent();
};
$(function() {
popList(5000);
});

Collapsing and Expanding lists in javascript

I'm using a tutorial to make collapsible lists in HTML.
My HTML looks like this:
<li>
hello
<ul id="node3" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
<li>
test
<ul id="node3" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
node 3,4,5,etc
I'm trying to collapse all these tables using the following JavaScript:
function test2(id, link) {
var e = document.getElementById(id);
if (e.style.display == '') {
e.style.display = 'none';
link.innerHTML = 'Expand';
} else {
e.style.display = '';
link.innerHTML = 'Collapse';
}
}
But when I call the function I'm not too sure what to enter to select all nodes. I still need the individual control on each node, so I can't change all the names to be the same.
Collapse
You could use the class attribute for that.
<li>
hello
<ul id="node1" class="node" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
<li>
test
<ul id="node2" class="node" style="display:none">
<li>Sub-item 1</li>
<li>Sub-item 2</li>
</ul>
</li>
Assuming that you really want to collapse all of them and not toggle their visibility you could write something like this...
function test2(className, link) {
var e = document.getElementsByClassName(className);
for (var i = 0, len = e.length; i < len; i++) {
e[i].style.display = "none";
}
link.innerHTML = "Expand";
}
...and call it like that...
Collapse
Keep in mind that getElementsByClassName does not work in older browsers (< IE9).
UPDATE:
An alternative way of achieving this is by using CSS and changing the class-name of a mutual parent element. Here's a sample CSS code for that:
#mutualParent.hide-nodes li.node {
display: none;
}
Then change your function like this...
function test2(className) {
document.getElementById("mutualParent").className += className;
}
...and call it like that:
Collapse
If you want to toggle the visibility using the test()-function you need to remove the className first or otherwise it stays hidden. Also for this code to work you need to remove the style-attribute from the <ul> tags because style attributes have a higher priority.

PrototypeJS: Selecting the odd subset of visible children

This is related to my previous question about selecting visible elements. Now, here's the twist: Let's say I want to select the odd children only from the set of visible children of an element. What would be the best way to do this?
Edit: here is an example of my input and expected output.
<!-- A list with some visible and invisible children -->
<ul class="stripe">
<li>Visible 1</li>
<li style="display:none;">Visible 2</li>
<li style="display:none;">Visible 3</li>
<li>Visible 4</li>
<li style="display:none;">Visible 5</li>
<li>Visible 6</li>
<li>Visible 7</li>
</ul>
<!-- Only the visible children. -->
<li>Visible 1</li>
<li>Visible 4</li>
<li>Visible 6</li>
<li>Visible 7</li>
<!-- The "odd" visible children. -->
<li>Visible 1</li>
<li>Visible 6</li>
I came up with two ways. One works, but the other doesn't.
// Method one: Returns the odd children whether they are visible or not. :(
var listChildren = $$("ul.stripe > li");
var oddChildren = allChildren
.findAll(function(el) { return el.visible(); })
.findAll(function(el) { return el.match("li:nth-child(odd)"); });
oddChildren.invoke("addClassName", "odd");
What I am currently doing now is the following:
// Method two: grouping!
var listChildren = $$("ul.stripe > li");
var oddChildren = listChildren
.findAll(function(el) { return el.visible(); })
.eachSlice(2, function(el) {
el[0].addClassName("odd");
});
This code seems like it could be improved. Can anyone suggest a better way to accomplish this?
The CSS select won't work for the application you desire, it doesn't work correctly on an Array outside of the context of the DOM.
You can do this as follows:
var index = 0;
var myChildren = $$("ul.stripe > li")
.select(function(e) { return e.visible(); })
.select(function(e) {return ++index % 2 == 1; });
Can't you merge the two conditions like this?
var listChildren = $$("ul.stripe > li");
var oddChildren = allChildren
.findAll(function(el) { return el.visible() && el.match("li:nth-child(odd)"); })
oddChildren.invoke("addClassName", "odd");

Categories

Resources