how to address list-items in the DOM - javascript

I've this markup
<ul id="body">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<li class="item">4</li>
</ul>
When an item is clicked, is there a way in jQuery to identify in the DOM, the previous and the next li so that I can use jQuery functions on those elements??
Say, if the person clicks on item 2, i want to hide item 1 and item 3.. similarly, if the user clicks on item 3, hide item 2 and item 4 (previous and next item in the list).

Get a pointer to the previous and next elements.
Select all siblings that are not the previous and next elements.
Hide the previous and next siblings.
Show the other elements.
This allows the code to work more than once :)
$('#body > li').click(function() {
var prev = $(this).prev(),
next = $(this).next(),
siblings = $(this).siblings().not(prev).not(next);
prev.add(next).hide();
siblings.show();
});
jsFiddle.
If you don't care if the other elements are hidden forever once clicked, simply remove the all references to the siblings variable and its relevant code.

$('#body .item').click(function() {
$(this).prev().add($(this).next()).hide();
});
Edit:
$('#body .item').click(function() {
$(this).siblings().show().end().prev().add($(this).next()).hide();
});
From the comment, This will show all before hiding the prev and next li elements.

Related

Function containing a for loop stops running after click event

I am trying to make a shopping list app that requires the following -
add items to list based on user input, and include a delete button.
toggle items being crossed off with a line through style.
remove items from list when delete button is clicked in corresponding li.
enter code here
The issue I am running into, is that I cannot cross off old list items after new list items are added.
I created a function that is a for loop to loop through the list and toggle the .done class on and off. it works to allow me to toggle line through on and off but as soon as a new item is added to the list through click or key press event, the function stops working.
I figured by placing the toggleDone(); inside of the functions inside of the click and keypress functions as well as globally, it would work on both newly added list items and the original list items.
what actually happens is if i click to add a new item to the list, it no longer functions on the original list items, and then if i keypress to add an item to the list, the function works on the old list items as well as the keypress items, but not the click items.
const input = document.getElementById("userInput");
const btn = document.getElementById("enter");
const ul = document.querySelector("ul");
const list = document.getElementsByTagName("li");
function toggleDone(){
for (let i=0; i < list.length; i++){
list[i].addEventListener("click", function(){
list[i].classList.toggle("done");
});
}
}
If I understand your question, you could simplify things by using event delegation technique. Attach a click event handler to the ul element instead of each individual li - this works because events propagate upward (aka bubbling). You can inspect the event.target passed to the callback function to see exactly what was clicked.
Here is an example demonstrating how to toggle a style on li elements using event delegation:
document.querySelector("ul").addEventListener("click", function(event) {
event.target.classList.toggle("done");
});
.done {
text-decoration: line-through;
}
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
You might not be calling the function in the right place
You should add if else statement when calling for loop
For the for loop don't say "let" (depends on version) say "var"
This link might help (example)
https://www.w3schools.com/howto/howto_js_todolist.asp

jQuery mega menu display only the clicked parent submenu

I have a simple Mega Menu. I am trying to display the sub menu of the parent menu item clicked. But for some reason when I click the parent item all the sub menu's are displaying instead of the clicked parent item sub menu. What I am doing wrong.
Here is my JSFiddle link
https://jsfiddle.net/jokcLjkb/4/
here is my js code.
$(document).ready(function() {
$("a.drop").on('click', function(e) {
e.preventDefault();
$("ul.mainNav li > .drop-full-col").css("display","block");
});
});
Thanks and Appreciate it
Your line:
$("ul.mainNav li > .drop-full-col")
Will select all the submenus because you target the main nav and all the <div class="drop-full-col"> elements. You need to select only the ones relative to the link you click on, and to do that you need to use this to refer to the link being clicked on. So change:
$("ul.mainNav li > .drop-full-col").css("display","block");
to
$(this).closest('li').find(".drop-full-col").css("display", "block");
jsFiddle example
.closest('li') will look for the closest list item when you click the link, and .find(".drop-full-col") will then search down the DOM for the div you want.

Moving <li> to another list need to update click listeners

See an example here: https://jsfiddle.net/06bf3w2c/1/
I have two <ul>s. Clicking an item in the second one will move that item to the first one.
In the first list each <li> contains a <span> with the class delete-btn. when this span gets clicked it should remove the item from the list.
This is working correctly except for when you move an item from the second list into the first list and then try to delete it. Once the delete-btn span of a moved item gets clicked it seems to still be registering the click listener for the second list even though it is no longer in the second list.
My click listener is applied like this:
$(".second li").click(function(){
$(".first").append($(this).append(' <span class="delete-btn">[ X ]</span>'));
});
after the li is moved and then the delete-btn span is clicked it calls this click listener even though the <li> no longer is a decedent to the second class.
How can I update the click listener when I move the <li> from the second list to the first so that the delete button listener will work after the item has been moved.
That's because you're attaching the click listener to the li's themselves. When the li is moved, it still has the click event listener and just duplicates itself. You should instead attach the event listeners to the lists and have it listen for clicks on child lis like so:
$(".second").on('click', 'li', function(){
$(".first").append($(this).append(' <span class="delete-btn">[ X ]</span>'));
});
$(".first").on('click', '.delete-btn', function(){
$(this).parent().remove();
});
ul{
float: left;
}
.second li{
background-color: #BABABA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="first">
<li>item 1 <span class="delete-btn">[ X ]</span></li>
<li>item 2 <span class="delete-btn">[ X ]</span></li>
</ul>
<ul class="second">
<li>item 3</li>
<li>item 4</li>
</ul>

Use jQuery to copy text from one location, to replace text elsewhere

I've been struggling with this for hours so hope someone can please help.
I have a dropdown menu (.category-navbar) which filters images shown below it. Whichever item is selected in the list is given the class '.select' - what I want is to have a label above that which displays the text of the selected list item.
<div class="dropdown-menu-portfolio">
<label>All</label> // This is the text I want to update
<ul class="category-navbar">
<li class="select">
<a>All</a>
</li>
<li>
<a>Item2</a>
</li>
<li>
<a>Item3</a>
</li>
<li>
<a>Item4</a>
</li>
</ul>
</div>
The label will initially show the text 'All' (as that is the default list item), but I want that to change when one of the other menu items are selected ie. 'Item2', 'Item3' etc.
Below is the code showing what I think I need, I've tried variations of this but nothing has worked - I've put 'copy' and 'replace' to show want I want to happen.
$(".category-navbar li a").click(function() {
$(this)
.copy(".select a").text()
.replace(".dropdown-menu-portfolio label").text();
});
Whilst trying to get anything to work, I found the code below does work, but obviously isn't right as it adds the newly selected item after the label, also it adds the text as a link, whereas I only want plain text.
$(".category-navbar li a").click(function() {
$(this)
.clone(".select a")
.appendTo(".dropdown-menu-portfolio label");
});
Any help would be much appreciated, thanks.
A simple solution would be:
$(".category-navbar li a").click(function() {
// Modifying the label
$('div.dropdown-menu-portfolio label').text($(this).text());
// Removing the class 'select' to the item previously selected
$('li.select').removeClass('select');
// Giving the class 'select' to the item currently selected
$(this).parent().addClass('select');
});
You're overthinking this. Just try
$(".dropdown-menu-portfolio label").text($(this).text());
Your syntax was wrong aside from this better solution.

Array item as list and nested list

I have a set of images for each background page and I am using an array to load each image based on the menu item I click. The menu items have sub menus too and the whole menu system shoudl be in "sync" with the array items:
html menu:
Home (page 1) (menu item hidden but should be "Menu 1" if it would be displayed)
<ul id="menu">
<li>Menu 2</li>
<li>Menu 3
<ul id="sub-menu">
<li>Menu 4</li>
</ul>
</li>
<li>Menu 5</li>
</ul>
Array:
[0] 1.jpg (image for the home where the menu name item isn't displayed)
[1] 2.jpg (this should be for Menu 2)
[2] 3.jpg (this should be for Menu 3)
[3] 4.jpg (this should be for Menu 4)
[4] 5.jpg (this should be for Menu 5)
When the site loads it reads [0] 1.jpg, which is for the home page. But the first item we can click is "Menu 2" since the "Home" button isn't displayed in the menu it should go to [1] 2.jpg.
This is the jQuery I use:
jQuery (function($) {
$("#menu .menu li").each(function (index) {
var item = $(this);
$("a", item).click(function (e) {
e.preventDefault();
api.goTo(index+1);
});
});
});
With "api.goTo(index+1);" (using supersized plugin here) I'm saying (or i think I am) on the first click of the menu item, go to index+1 which supposed to be [1] but it isn't, it looks like it is still [0] which is used for the home page tho. Also, i thougth nested items would still follow the index sequence.
Basically I can't get the correct image for the correct page. It's like I'm not navigating the array according to the menu item i click.
P.s. Index in this case is the 0 based index of the item in jquery loop
I have no idea what you're doing, but you are binding click functions inside a loop using a variable, the variable will change, and the result will not be what you expected.
Maybe this will help ?
$('a', 'li').on('click', function(e) {
e.preventDefault();
var index = this.href.replace('page', '');
api.goTo(index);
});
Because of the submenu just getting the right number from the href on click seems easiest.
When referencing values in an array you have do :
var index = ['1.jpg', '2.jpg', '3.jpg'] //an array, starts with zero
var firstimage = index[0]; //this variable is now the string "1.jpg"
I'm guessing you are just passing a number to the api.goTo(number) function, and that function finds the image link in your array, at least that's what it looks like to me ?

Categories

Resources