How to delete an element which does not have a certain parent? - javascript

I want to delete list items who do not have a parent of ul
This is my HTML:
<div class="yamm-content">
<div class="row">
<li> Should be deleted
</li>
<li> Should be deleted
</li>
<ul id="randomid" class="col-xs-12 col-sm-4">
<li> menu item
</li>
<li> menu item
</li>
<li> menu item
</li>
</ul>
<ul id="randomid2" class="col-xs-12 col-sm-4">
<li> menu item
</li>
<li> menu item
</li>
<li> menu item
</li>
</ul>
</div>
</div>
and my current script:
if (!$('.nav .yamm-content row li').closest('ul').length == 0) {
$(this).remove();
}
jsFiddle
The first two list items don't have ul's as parents. So they should be deleted.

Simple: $('li:not(ul > li)').remove();
Demo http://jsfiddle.net/46NdQ/3/

$('li').filter(function(){return !$(this).closest('ul').length}).remove();
Or
$('li').not($('ul li')).remove();

Here i used Javascript only and it may take some lines of coding. I suggest this may be useful some times when you don't want to go for jquery.
var len = document.getElementsByTagName('li').length;
for (var i=0;i<len;i++)
{
if (document.getElementsByTagName('li')[i].parentNode.nodeName != "UL")
{
document.getElementsByTagName('li')[i].remove();
i--;
}
}
Here is the fiddle

Related

How to prevent all parents from toggling when clicking on child link jquery?

So I have something like this:
And some ultra simple jQuery that is toggling the child links when I click the parents ("Spec Sheet", "Instructions" etc) although when I click on one, they all open. Here is the code (is there a simple way to only open one parent per click)?:
$(document).ready(function(){
$("ul#dropdown-download-links li > a").unbind().click(function(e) {
var ulContainer = $(this).closest("ul");
e.preventDefault();
$(ulContainer).slideToggle();
});
});
$(this).closest("ul"); is targeting the wrong element, this targets the first parent ul encountered going up the DOM tree from the clicked a tag
In the below $(this).closest("li").find("ul"); will target the first parent li tag encountered going up the DOM tree from the clicked a tag, then find the ul tag inside that li tag
$(document).ready(function() {
$("ul#dropdown-download-links li > a").unbind().click(function(e) {
var ulContainer = $(this).closest("li").find("ul");
e.preventDefault();
$(ulContainer).slideToggle();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sticky-sidebar">
<ul class="dropdown-menu">
<li>
Where to Buy
</li>
<li>
<ul id="dropdown-download-links" data-sticky="sticky-aside" class="fast-links dropdown">
<div data-domain="http://wacdev.waclighting.com" style="display:none;"></div>
<div data-zspectempid="" style="display:none;">0</div>
<div data-ppid="" style="display:none;">333</div>
<div data-spec-sheet-url="" style="display:none;">/storage/SPECSHEET_PDF/R3CRDT_SPSHT.pdf</div>
<li>SPEC SHEET
<ul id="spec-sheet-option" style="display: none;">
<li><span class="glyphicon glyphicon-align-left" aria-hidden="true"></span>Oculux Architecture</li>
<li>Dim-to-Warm!</li>
</ul>
</li>
<li>INSTRUCTIONS
<ul id="spec-sheet-option" style="display: none;">
<li>Oculux Architecture</li>
<li>Dim-to-Warm!</li>
</ul>
</li>
<li>IES FILES
<ul style="display: none;">
<li>Some value</li>
<li>Some other value</li>
</ul>
</li>
<li>DIMMING REPORT
<ul style="display: none;">
<li>Some value</li>
<li>Some other value</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

Nested function calls from the second click

I have multiple <li> elements. When I click to one of this, data from the chosen <li> should populate fields of form below. But my problem is when I click on the list of <li> tags it works from the second click.
<div class='js-delivery-addresses' id='delivery_addresses'>
<ul>
<li> one </li>
<li> two </li>
<li> three </li>
</ul>
</div>
Js code:
events: {
"click .js-delivery-addresses": "chosenAddress"
}
chosenAddress: function() {
...some code here;
$('#delivery_addresses li').unbind().on('click', function() {
...other code that works from second click;
})
}
I expect it will work from the first click.
Is this not much simpler ?
$(document).on("click","#delivery_addresses ul li",function(){
alert($(this).val() + " = " + $(this).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='js-delivery-addresses' id='delivery_addresses'>
<ul>
<li> one </li>
<li> two </li>
<li> three </li>
</ul>
</div>

How to find nth p element?

I want to find the 3rd p tag of each category, based on first p tag's value.
e.g. The first p tag value is Tie, then find the quantity of it.
If the html element tree should be formatted in a better way, I am open to it. The html for all ul is written from code behind at C# to load items from database.
$("#wel div ").each(function(index, element) {
if ($(this).('p:nth-of-type(1)').html() == "Tie")
{
$(this).('p:nth-of-type(3)').css('background-color','red');
}
}
<div id="fel">Category1
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p> <!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
<div id="wel">Category2
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p><!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
JSFiddle
You can 2 top level elements with different ids fel and wel so need to use #wel div, #fel div to find the category div elements, then need to use .find() to find the p
$("#wel div, #fel div").each(function (index, element) {
if ($(this).find('p:nth-of-type(1)').html().trim() == "Tie") {
$(this).find('p:nth-of-type(3)').css('background-color', 'red');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="fel">Category1
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
<div id="wel">Category2
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
You can also do
$("#wel div, #fel div ").each(function (index, element) {
var $ps = $(this).find('p');
if ($ps.eq(0).html().trim() == "Tie") {
$ps.eq(2).css('background-color', 'red');
}
})
Demo: Fiddle
Here's the generic way of doing it
$(document).ready(function(){
var div = $('p:contains("Tie")').parent()
$('p:contains("Tie")').parent()
var price = $(div).find("p:contains('Price')").css('background-color','red');
console.log(price)
});
Please refer the fiddle here

How to close all elements that are opened with jquery? (Behavior similar to the accordion menu)

I have this html code:
<div id="menu">
<ul id="menuFuncionalidades">
<li>
<div class="menuFuncionalidades_categoria">
Index</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Cadastros</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul><b>Acesso Usuario</b>
<li>Pesquisar </li>
<li>Incluir </li>
<li>Alterar </li>
<li>Consultar </li>
</ul>
<ul><b>Produto</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul><b>Perfil</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Coletores</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul>
<b>Coletor 1</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 2</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 3</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
</ul>
</div>
My objective is when i click in a menuFuncionalidades_categoria i close all menuFuncionalidades_content_links that is opened, and opened the right one that is in the same level of the menuFuncionalidades_categoria that i click. So, i try this, but i have no success:
$(document).ready(function () {
$('#menuFuncionalidades > li > .menuFuncionalidades_categoria').click(function () {
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
// I need a code here to close only the tags that are opened but is not the current
if ($(this).css('display') == 'block') {
$(this).hide();
}
});
$(this).parent().find('.menuFuncionalidades_content_links').slideToggle('normal').css('width', $('#menu').css('width'));
});
});
What am i missing or doing wrong?
OBS: The behavior that i want, is similar with accordion menu.
DEMO here: http://fiddle.jshell.net/ry9dz/1/
As #karim79 says, you can't check "display" that way - it's a css attribute, not an html attribute.
On the other hand, if you want to close all other entries, then just do that - no need to check if they are visible first! I also suggest you use a more efficient event handler for all your items, instead of binding it to all of them. Using jQuery 1.7, something like this would work:
$(document).ready(function () {
$("#menuFuncionalidades").on("click", ".menuFuncionalidades_categoria", function(event) {
var selectedMenu = $(event.target).parents("li").find(".menuFuncionalidades_content_links")
, visible = selectedMenu.is(":visible");
// Hide all others
$("#menuFuncionalidades .menuFuncionalidades_content_links").hide();
// Show this one unless it was already visible
if(!visible) {
selectedMenu
.slideToggle('normal')
.css('width', $('#menu').css('width'));
}
// Prevent the default action
event.preventDefault();
});
});
You can hide multiple elements without iterating though all of them to see which ones aren't hidden.
Replace;
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
if ($(this).attr('display') == 'block') {
$(this).hide();
}
});
with;
$("#menu").find('.menuFuncionalidades_content_links').hide();
$(this).attr('display') is invalid as there are no "display" attribute and instead of using .css('display') == 'block' you could simply use the psuedo selector :visible.
You want the display css property:
if ($(this).css('display') == 'block') {
$(this).hide();
}
or:
if ($(this).is(':visible')) {
$(this).hide();
}

jquery collapsible menu help - almost there, but need 2 levels deep collapsible too!

I've taken the accordion menu from http://www.i-marco.nl/weblog/ and have customised it to what I need. One problem I have though is that I have a couple of submenu items which are also collapsible. The code I have works fine in terms of collapsing the menu, but I can't get it to retract this menu when the parent element is clicked. Can anyone see where i'm going wrong here?
Thanks in advance!
HTML snippet:
<ul class='menu collapsible' id='menu'>
<li id="home" class="selected expand top">
Home
</li>
<li id="about_the_school" class="top">
About the School<span>Click to expand</span>
<ul class='acitem'>
<li>
Welcome
</li>
</ul>
</li>
<li id="academic" class="top">
Academic<span>Click to expand</span>
<ul class='acitem'>
<li>
Curriculum & Exam System
</li>
<li>
Departments
<ul class='acitem menu collapsible'>
<li>
Art
</li>
<li>
Business Education
</li>
</ul>
</li>
<li>
Pupil Support
</li>
<li>
Careers
</li>
</ul>
</li>
</ul>
</ul>
JS:
jQuery.fn.initMenu = function(){
return this.each(function(){
var theMenu = $(this).get(0);
$('.acitem', this).hide();
$('li.expand > .acitem', this).show();
$('li.expand > .acitem', this).prev().addClass('active');
$('li a', this).click(function(e){
e.stopImmediatePropagation();
var theElement = $(this).next();
var parent = this.parentNode.parentNode;
if (theElement.hasClass('acitem') && theElement.is(':visible')) {
if ($(parent).hasClass('collapsible')) {
$('.acitem:visible', parent).first().slideUp('normal', function(){
$(this).prev().removeClass('active');
});
return false;
}
return false;
}
if (theElement.hasClass('acitem') && !theElement.is(':visible')) {
//custom - adds class at beginning of expansion
$(this).addClass('active');
$('.acitem:visible', parent).first().slideUp('normal', function(){
$(this).prev().removeClass('active');
});
theElement.slideDown('normal', function(){
$(this).prev().addClass('active');
});
return false;
}
});
});
};$(document).ready(function(){
$('.menu').initMenu();
});
On this section:
<a href="http://localhost//public_html/index.php/academic">Academic
<span>Click to expand</span>
</a>
<ul class='acitem'>
You need a collapsible class on that <ul> to get it to collapse as well, same the others, like this:
<ul class='acitem collapsible'>
You can see an updated/working demo with the fix here.

Categories