Append sub-elements to its parent element only - javascript

I am trying to convert a bunch of menu dropdowns into multiple elements. I have been able to do this when theres only one dropdown on the page but once I add the others, my script seems to run through each menu multiple times. I am new to Javascript/Jquery but I was wondering if there was a way to make it only input to its parent element?
Here is my current script that works for a single dropdown:
$('.mylinks li').each(function() {
var inputClass = $('.mylinks .link').html().toLowerCase();
$('body').prepend('<select class="'+inputClass+'" onchange="window.location.href=this.options[this.selectedIndex].value"></select>');
$('a').each(function() {
var linkName = $(this).html();
var linkVal = $(this).attr('href');
$('select').append('<option value="'+linkVal+'">'+linkName+'</option>');
});
});
HTML
<div class="mylinks">
<ul>
<li>
Drop 1
Link 1
Link 2
Link 3
</li>
<li>
Drop 2
Link 1
Link 2
Link 3
</li>
</ul>
</div>
I have an example of this error here as well: http://jsfiddle.net/UdTcF/

You can try this code:
$(document).ready(function () {
$('.mylinks li').each(function () {
var inputClass = $('.mylinks a').html().toLowerCase();
var select = $('<select class="' + inputClass + '" onchange="window.location.href=this.options[this.selectedIndex].value"></select>');
$('body').prepend(select);
$(this).find('a').each(function () {
var linkName = $(this).html();
var linkVal = $(this).attr('href');
select.append('<option value="' + linkVal + '">' + linkName + '</option>');
});
});
});
Use a variable select to save the <select> you want to add, and late can add <option> to this variable using select.append().
And use $(this).find('a') instead of $('a') to find <a> in certain <li> but not all <a>.
Here is jsfiddle.

Here:
$('a').each,
you're selecting all a elements. I think that you want to select just only those in the current li. SO, just replace add:
$('a',this).each,
it will select only a elements which are children of this, eg the li element.

Related

jQuery function non-reversible. [website cart feature]

I'm pretty new to the world of jQuery and having some difficulty with a cart feature I am trying to add to a website.
I have created a function to add an element (based on its id) to the cart. This works fine. However when I try to reverse it (say someone clicks on the cart icon again to remove it) the cart count increases more and the class doesn't change back.
You will see in my code I am changing the classes for visual representation (unselected = svg with no fill & selected = svg with fill).
I have tried toggling the class, removing and adding the class but I can't think of much more. Any help would be greatly appreciated!
$(document).ready(function() {
var cart = [];
$("a.addToCart").click(function(event) {
var pressedId = event.target.id;
$("#cart_button").removeClass("hidden");
$("#" + pressedId).removeClass("addToCart");
$("#" + pressedId).addClass("addedToCart");
cart.push(pressedId)
$('.cart--counter').html(cart.length);
});
});
$(document).ready(function() {
$("a.addedToCart").click(function(event) {
var unpressedId = event.target.id;
$("#" + unpressedId).addClass("addToCart");
$("#" + unpressedId).removeClass("addedToCart");
cart.splice( $.inArray(unpressedID,cart) ,1 );
$('.cart--counter').html(cart.length);
});
});
Here is an example of the HTML with a class and ID.
<a id="12" class="addToCart">
Again, for clarification: the class changes appropriately from "addToCart" to "addedToCart" but is not reversible & the array is successfully updated with appropriate "ID" but can not be removed again.
Your issue is that when you add your event handlers, there are no elements with class addedToCart, so no event handlers get assigned. You need to use a delegated event handler instead:
var cart = [];
$(document).ready(function() {
$(document).on('click', "a.addToCart", function(event) {
var pressedId = event.target.id;
$("#cart_button").removeClass("hidden");
$("#" + pressedId).removeClass("addToCart");
$("#" + pressedId).addClass("addedToCart");
cart.push(pressedId)
$('.cart--counter').html(cart.length);
$('#cart').html(cart.toString());
});
});
$(document).ready(function() {
$(document).on('click', "a.addedToCart", function(event) {
var unpressedId = event.target.id;
$("#" + unpressedId).addClass("addToCart");
$("#" + unpressedId).removeClass("addedToCart");
cart.splice($.inArray(unpressedId, cart), 1);
$('.cart--counter').html(cart.length);
$('#cart').html(cart.toString());
});
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="12" class="addToCart">Item 12</a><br />
<a id="13" class="addToCart">Item 13</a>
<div class="cart--counter">**</div>
<br />
<div id="cart"></div>
<br />
<div id="cart_button" class="hidden">cart button</div>

Jquery Remove Element from List

I have a list in JQuery that's called additionalInfo, which is filled in using this JQuery function:
$('#append').on('click', function () {
//check if the following area is valid before moving on, check the jquery validation library
var text = $('#new-email').val();
var li = '<li>' + text + 'input type="hidden" name="additionalInfo" value="'+text+'"/> </li>';
$('#additional-info-list').append(li);
$('#new-email').val('');
});
The point of the function is not only to store the info in a list that can be used later, but also to render a <li> with the info text in it. Right now I have another button on each <li> that when pressed, makes the li vanish, but I also need to add code to it that completely removes the info text from the additionalInfo list. This is the code I have for that method so far:
$('#removeEmail').on('click', 'li>.remove-btn', function (event){
$(event.currentTarget).closest('li').remove();
});
How can I get the segment of info text out of the li and then remove it from additionalInfo?
You have few problems. First of all when you create the new items, your markup is not correct. You were missing the opening bracket of input tag. Also i changed the code for delete so that it listens for the click event on any item with class remove-btn under the li element. This should delete the item when you click the remove link inside the li.
$(function(){
$('#append').on('click', function () {
var text = $('#new-email').val();
var li = '<li>' + text + '<input type="hidden" name="additionalInfo"
value="'+text+'"/>
<a href="#" class="remove-btn" >remove</a></li>';
$('#additional-info-list').append(li);
$('#new-email').val('');
});
$(document).on('click', 'li>.remove-btn', function (event){
var _this =$(this);
_this.closest('li').remove();
});
});
Here is a working jsfiddle

Clicking list item creates a new list item with the original list item's text content

I have 2 ol, on click of an li in the first ol I create an li in the second ol. I would like to set the text content of the newly created li with that of the first, clicked li. Example: 'item 1'.
Here's my JQ:
$(document).ready(function() {
$("li").click(function() {
$(".secondlist").append('<li>placeholder</li>');
});
});
Here's my JS Bin
Thanks in advance for your help.
Use jQuery#append and then declare a text variable equal to the text of the clicked list item. You will be appending this value.
$("li").click(function() {
var current = $(this).text();
$(".secondlist").append("<li>" + text + "</li>");
});
Here is the updated fiddle
http://jsfiddle.net/vk80f7f5/1/
You can use one of this variants:
$("li").click(function() {
$(".secondlist").append($(this).clone());
//$(".secondlist").append('<li>' + $(this).html() + '</li>');
//$(".secondlist").append('<li>' + $(this).text() + '</li>');
});
and if you will use clone() you may not use '<li>' and '</li>'

Jquery - find closest text by class

Here is my HTML and script. I simply want to find the text of what is clicked, and include the text of it's previous element with a certain class, in the alert. Elements are not necessarily children/parents here.
So, if Prince5 is clicked, the alert should read King1: Queen3: Prince5
I'm close, but it's currently always giving the text as Queen1, since it's the first text in that column.
Any ideas?
<li class="king"><a href="#" >King1</a>
<span class="column1">
<li>Queen1</li>
<li> Prince1</li>
<li> Prince2</li>
<br>
<li>Queen2</li>
<li> Prince3</li>
<li> Prince4</li>
<br>
<li>Queen3</li>
<li> Prince5</li>
<li> Prince6</li>
</span>
<script type="text/javascript">
$("li a").click(function() {
var three= $(this).text(),
one = $(this).closest('.king').find('a:first').text();
two = $(this).closest(".column1").find("a.queen:first").text();
alert(one + ":" + two + ":" + three);
});
</script>
There are a number of problems with the HTML shown. A span is not a valid parent for the LI elements so I added a UL.
Basically you can go back up the ancestors of the clicked link, then sideways through previous siblings (that match .queen), then down again to the link on the first match:
$("li a").click(function () {
var three = $(this).text(),
one = $(this).closest('.king').find('a:first').text();
two = $(this).closest("li").prevAll("li:has(a.queen)").first().find('a').text();
alert(one + ":" + two + ":" + three);
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/7q3e9p7g/1/

Jquery .next() not working as expected

On my website, I have an unordered list that is originally unpopulated. After the page loads, I use jquery and ajax to call a php page that loads data in from a database. It then returns that data to the ajax call so that it can create a bunch of list items and append them to the unordered list.
Each of these list items can be selected. When they are selected, I append a class to them called "selected-li" which just underlines the text. I also have arrows to navigate between the list items (i.e. up-arrow and down-arrow). I thought that the following would work...
$("#down-arrow").click(function(){
$(".selected-li").next().addClass("selected-li");
});
...and it does, just not as expected. I have to click the down arrow twice in order for the class to be added to the next item. For some reason, it thinks that there is an invisible list item in between each of the ones displayed.
As a fix, I did the following:
$("#down-arrow").click(function(){
$(".selected-li").next().next().addClass("selected-li");
});
It works now, but why does this happen? Why does it think that there is an extra li in there?
HTML code:
<div id="up-down-arrows">
<img id="up-arrow" height="35px" width="35px" src="/../images/circle_arrow_up.png"></img><br><br><br>
<img id="down-arrow" height="35px" width="35px" src="/../images/circle_arrow_down.png"></img>
</div>
<div id="article-list"><ul id="unordered-list"></ul></div>
Javascript code on return from ajax call:
function(data){
for(var i = 0; i < data.length; i++){
title = data[i]["name"];
$("#unordered-list").append('<li title="' + title + '">' + title + '</li><br>');
}
}
It's the <br> tag. The .next() function gets the next sibling element, not the next <li> element. Besides it's not valid html to have a <br> between <li> elements.
Even if you find the reason why you have to call .next() twice, is this really going to do what you want? There could be multiple items with the "selected-li" class, and your code will then add that class to the items that are after each of them. That is, if items 3 & 7 are selected, Items 4 & 8 will also be selected after the down button is clicked. Here's a jsfiddle showing this.
LIVE DEMO
.next() or no .next()... The <ul> tag is not supposed to hold <br> but list tag <li>.
Additionally I would suggest going like:
This will also loop the selected LI element on buttons click.
var $ul = $('#unordered-list');
var liData = ""; // Popoulate string and append only once to UL (see below)
var $li; // Reference to future created LI
var liN; // Will hold the number of LI after creation
var sel = 0; // Selected index
$.ajax({
dataType: "json",
url: 'yourFile.json',
success : function(data){
for(var i = 0; i < data.length; i++){
title = data[i].name;
liData += '<li title="' + title + '">' + title + '</li>'; // <br>? c'mon..
}
$ul.append( liData ); // Append only once (performance matters!)
$li = $('li', $ul); // Find appended LI - put in collection
liN = $li.length; // How many?
$li.eq(sel).addClass('selected-li'); // (add class to first)
}
});
$('#up-arrow, #down-arrow').click(function(){
sel = (this.id.match('down') ? ++sel : --sel) % liN ;
$li.removeClass('selected-li').eq(sel).addClass('selected-li');
});

Categories